I am using following meta tags to prevent browser caching for page:
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate, max-stale=0, post-check=0, pre-check=0" />
<meta http-equiv="Pragma" content="no-cache" />
<meta http-equiv="Expires" content="-1" />
<meta http-equiv="Vary" content="*" />
Case:
page1
.page2
is opened.page2
and is redirected to page3
.When clicking back button on page3
, then user gets redirected to page1
(no caching and works fine in this case). When user clicks forward button on page1
, then the user is forwarded to the secured page page2
. This shouldn't happen.
All of above is tested on IE9.
How is this caused and how can I solve it?
header("Pragma: no-cache"); // HTTP 1.0.
function disableBackButton() { window. history. forward(); } setTimeout("disableBackButton()", 0);
Back/forward cache (or bfcache) is a browser optimization that enables instant back and forward navigation. It significantly improves the browsing experience for users—especially those with slower networks or devices.
Your initial attempt with HTML <meta http-equiv>
tags specifies the right header values, however, this doesn't work at all because your pages are already served over HTTP. The <meta http-equiv>
headers specifies "HTTP-equivalent" headers which are only used when the pages are not served using the HTTP protocol.
For example, when the pages are opened from local disk file system like as if you were doubleclicking a .html
file in local disk file system explorer. This would open the .html
file via file://
URI instead of http://
URI.
You should be setting those headers on the real HTTP response. You can investigate the headers of the current HTTP response by pressing F12 in Chrome/FireFox>=23/IE>=9 and exploring the HTTP traffic in Network tab. In case of specifically IE9/10, click the Start capturing button, reload the page, select the HTML page, click Go to detailed view button and finally click the Response headers tab. Here's a screenshot of how it look like in IE10 on your current question:
The right way to get those headers to end up there is using HttpServletResponse#setHeader()
and friends like setDateHeader()
, addHeader()
, etc. As you figured, one way is a servlet filter.
I found out that the best solution is the following filter:
import java.io.IOException;
import javax.faces.application.ResourceHandler;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet Filter implementation class NoCacheFilter
*/
@WebFilter(urlPatterns = {"*.xhtml"})
public class NoCacheFilter implements Filter {
/**
* Default constructor.
*/
public NoCacheFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
/**
* @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
*/
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// apply no caching for all web pages except resources, you can customize that to be applied for specific pages
if (!req.getRequestURI().startsWith(req.getContextPath() + ResourceHandler.RESOURCE_IDENTIFIER)) { // Skip JSF resources (CSS/JS/Images/etc)
res.setHeader("Cache-Control", "no-cache, no-store, must-revalidate"); // HTTP 1.1.
res.setHeader("Pragma", "no-cache"); // HTTP 1.0.
res.setDateHeader("Expires", 0); // Proxies.
}
chain.doFilter(request, response);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
according to the answer in this question:
Redirect to login page when user clicks on back button after logout in JSF
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With