当用户单击浏览器的后退按钮时,您会看到上一页,这表明页面已缓存,并且从浏览器的缓存中显示,而不是从服务器请求的页面。要修复它,你需要适当地设置HTTP响应头。这已在Making sure a web page is not cached, across all browsers中事先得到解答。只是重复BalusC,它们是:
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
最合适的地方设置这些标题是网页过滤器,你似乎并不需要任何JSF财物那里。您可以在Avoid back button on JSF web application的答案中找到更多信息。要重复BalusC的代码,您将拥有:
@WebFilter("/secured/*")
public class NoCacheFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
if (!request.getRequestURI().startsWith(request.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
response.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
response.setHeader("Pragma", "no-cache"); // HTTP 1.0.
response.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(req, res);
}
// ...
}
只要不要忘记告诉您需要过滤哪些页面。这样,所请求的新页面将始终从服务器发送,而不会再被缓存。因此,如果用户在注销发生后尝试访问受保护的页面(通过会话失效并发送重定向),则您的标准安全手段将会启动(其他过滤器),从而阻止用户访问这些页面。
接下来要做的事情是解释JSF如何在会话失效/超时时处理已打开的页面。换句话说,你如何处理ViewExpiredException
s。对于同步POST请求,这又在How to handle session expiration and ViewExpiredException in JSF 2?和javax.faces.application.ViewExpiredException: View could not be restored中进行了回答,对于AJAX请求在Session timeout and ViewExpiredException handling on JSF/PrimeFaces ajax request中进行了回答。
基本上,对于前者,你需要以下几行添加到你的web.xml:
<error-page>
<exception-type>javax.faces.application.ViewExpiredException</exception-type>
<location>/expired.xhtml</location>
</error-page>
对于后者,我热烈推荐你看看JSF工具库OmniFaces及其FullAjaxExceptionHAndler这是为此设计。
[避免JSF Web应用程序上的后退按钮](http:// stackoverflow。com/questions/10305718/avoid-back-button-on-jsf-web-application) – BalusC
非常感谢@BalusC,但我的问题仍然不是在单击后退按钮上完全缓存页面,而是在缓存页面上,为什么在点击时执行操作的命令按钮,如果我无效的会话 –