After doing a code release last week, we discovered that our application had a caching issue since some of the .js files we changed weren't getting loaded properly. This was a surprise to us since we have html meta tags on each page for no caching and we also have included the no caching directives in our http response headers.
So what's going on? it had to do with the matter in which we included the no caching directives in our http response header. Our site uses sitemesh and we decided to include those directives in our sitemesh main decorator page. Big mistake, because sitemesh has a bug, and for some reason, it can't recognize the jsp scriptlets that we used to add the no caching directives.
Our solution? provide a filter that sites in front of our application that filters that applies the no caching directives to our secured pages and our javascript resources. (note, you need to modify the below code before using.. read the rest of the article to see why)
Looks familiar? well this is definitely related to my earlier post. I guess now, I know the root cause. I guess I should have also read that article more closely last time. This part is incredibly interesting since microsoft themselves recommends you to use the no cache directives...
My updated solution modifies my filter to provide an exclusion list so that I don't add any "no caching" directives on downloaded content. All the other pages will have the protection of "no caching". If anyone has better ideas, please feel free to comment and share your ideas!
Appendix:
Here are a list of other references i found related to this problem:
- It seems the the issue occurs in ie7 as well.
- a long list of related issues or different descriptions of the same issue.
So what's going on? it had to do with the matter in which we included the no caching directives in our http response header. Our site uses sitemesh and we decided to include those directives in our sitemesh main decorator page. Big mistake, because sitemesh has a bug, and for some reason, it can't recognize the jsp scriptlets that we used to add the no caching directives.
Our solution? provide a filter that sites in front of our application that filters that applies the no caching directives to our secured pages and our javascript resources. (note, you need to modify the below code before using.. read the rest of the article to see why)
import java.io.IOException; 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.http.HttpServletResponse; /** * * adds the no caching directives into the http response header * see: * http://en.wikipedia.org/wiki/List_of_HTTP_headers * http://www.i18nguy.com/markup/metatags.html * */ public class NoCachingFilter implements Filter { private static final String CACHE_CONTROL_PARAM ="Cache-Control"; private static final String CACHE_CONTROL_VALUE ="no-cache"; private static final String PRAGMA_PARAM = "Pragma"; private static final String PRAGMA_VALUE = "no-cache"; private static final String EXPIRES_PARAM = "Expires"; private static final int EXPIRES_VALUE = 0; private FilterConfig filterConfig = null; public void init(FilterConfig filterConfig) throws ServletException { this.filterConfig = filterConfig; } public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) servletResponse; response.setHeader(CACHE_CONTROL_PARAM,CACHE_CONTROL_VALUE); response.setHeader(PRAGMA_PARAM,PRAGMA_VALUE); response.setIntHeader(EXPIRES_PARAM,EXPIRES_VALUE); // continue with remaining filters filterChain.doFilter(servletRequest, servletResponse); //note: must be done before else the response is already commited. } public void destroy() { filterConfig = null; } }That was mistake number 2. After a round of testing, we discovered that some of our file downloads would not work, namely, we ran into this internet explorer bug.
Internet Explorer file downloads over SSL do not work with the cache control headers. This issue may occur if any one or more of the following conditions are true: The Do not save encrypted pages to disk check box is selected in Internet Explorer 6.0 SP1. The server sends the "Cache-Control: No Store" header. The server sends the "Cache-Control: No Cache" header.
Looks familiar? well this is definitely related to my earlier post. I guess now, I know the root cause. I guess I should have also read that article more closely last time. This part is incredibly interesting since microsoft themselves recommends you to use the no cache directives...
Are you using the Cache-Control header with the ASP "Response.CacheControl" property or through a returned HTTP header? This is the only way to truly prevent caching in Internet Explorer
My updated solution modifies my filter to provide an exclusion list so that I don't add any "no caching" directives on downloaded content. All the other pages will have the protection of "no caching". If anyone has better ideas, please feel free to comment and share your ideas!
Appendix:
Here are a list of other references i found related to this problem:
- It seems the the issue occurs in ie7 as well.
- a long list of related issues or different descriptions of the same issue.