When you setup a web server there are generally two types of caching that you need to configure:
- HTML resources are expired immediately so that any changes made to a site are quickly picked up by existing users.
- You set everything else (e.g. images, CSS, Javascript) to expire at some distance time in the future.
This caching scheme is covered in Two Simple Rules for HTTP Caching along with some ideas about how to manage changes.
Now that HttpWatch 6.0 supports Firefox we wanted to cover some differences in the way that it handles caching compared to Internet Explorer. The use of long expiration times (item 2 above) still directly applies to Firefox but there are some subtle differences in the configuration of item 1.
In the previous post, we broke item 1) down into:
- Sometimes dynamic HTML pages need to be fetched from the server whenever they are displayed - even when the back button is used. For example, pages showing the state of a bank account or online order.
- Static HTML pages, such as contact pages, FAQs or sitemaps, can make use of caching if they have a
Last-Modifiedresponse header allowing the brower to revalidate them as required
The rest of this post covers two important differences in Firefox that the affect caching of HTML pages.
1. Using no-cache Doesn’t Stop Caching in Firefox
You can prevent any caching in IE by simply setting this response header:
Cache-Control: no-cache
Pages that use this header aren’t stored in the cache and IE will always reload them from the server; even if you use the Back button to reach them.
Here’s an example in the HttpWatch online store where we show that an order has already been processed if you click on Submit button followed by the Back button:
Of course, we always redirect POST requests to a GET to avoid breaking the Back button.
However, this response header doesn’t prevent caching in Firefox. It just means that Firefox will never read the page from the cache during a normal visit unless it has been re-validated by sending a GET request. Also, if the page is reached using the Back button there’s no round-trip to the server and Firefox simple re-loads the page directly from the cache.
So how can caching be turned off in Firefox? The simple answer is that it cannot. Firefox relies on having a copy of every page in the cache for commands such as File->Save As and View Page Source. However, you can control where the page is cached and whether the cached entry can be used for display purposes.
The following response header in Firefox prevents persistent caching, by forcing the page into the in-memory cache:
Cache-Control: no-store
This header also prevents reuse of the cached version of the page and triggers an HTTP GET if the page is navigated to using the Back button.
These two header values can be combined to get the required effect on both IE and Firefox:
Cache-Control: no-cache, no-store
As shown here in the HttpWatch header tab:
UPDATE: The lack of no-cache support is limited to early versions of Firefox 3.0 and was caused by a bug. Although, no-cache alone should now work it is possible that visitors to your site will be running affected versions of Firefox.
2. If You Don’t Specify an Expiration Date Firefox May Set One for You
When IE encounters an HTTP response with no Expires header it just assumes that it can never automatically reuse the cached entry without re-validating it against the server. With the default setting of ‘Check for newer versions of stored pages’ in IE set to ’Automatically’, it will normally do this just once per session.
This provides a reasonable way of controlling the caching of static HTML content. The user will get the latest version if they open a fresh copy of IE and the cached version of the page will be used until they close IE.
Firefox handles the lack of an Expires header differently. If there is a Last-Modified response header it uses a heuristic expiration value as specified in the HTTP 1.1 spec RFC2616:
Also, if the response does have a Last-Modified time, the heuristic
expiration value SHOULD be no more than some fraction of the interval
since that time. A typical setting of this fraction might be 10%.
The calculation is as follows:
Expiration Time = Now + 0.1 * (Time since Last-Modified)
For example, if the last change to your static HTML file was 100 days ago, the expiration date will be set to 10 days in the future. Here’s an example from the Cache tab in HttpWatch of a page that had no Expires header:
Firefox has automatically set an expiration date in 8 days time because the page has not changed for approximately 80 days.
This means that to retain control of your HTML pages, as we discussed in Two Simple Rules for HTTP Caching, you should set up a suitable Expires header value on your web server for your HTML content as well as other resources such as images and CSS files.
Conclusions
In order to ensure consistent caching behaviour with IE and Firefox you should:
- Always specify an
Expiresheader. It will normally be set to -1 for immediate expiration of HTML pages or a date well into the future for other resources such as images, CSS and Javascript - If you want to force a page to be reloaded, even with the Back button, then use Cache-Control: no-cache, no-store



15 Comments
“Also, if the page is reached using the Back button there’s no round-trip to the server and Firefox simple re-loads the page directly from the cache.”
It’s a bug of Firefox 3.
https://bugzilla.mozilla.org/show_bug.cgi?id=441751
Pascal,
That bug appears to be related to using the back button to visit a page that was the direct result of a POST.
That’s a not a good idea as it breaks the back button:
http://blog.httpwatch.com/2007/10/03/60-of-web-users-can%e2%80%99t-be-wrong-%e2%80%93-don%e2%80%99t-break-the-back-button/
It you always redirect a POST to a GET then the no-store cache directive fixes the problem.
Hi,
i am working with some caching issues. I have some javascript code which loads images from various websites, and refreshes these images, by simply clearing the source of the img or by changing the background of the iframe, depending on the type of display. However, I have found that in many cases, Firefox doesn’t reload the image from source but uses the cached version; and this despite the fact that there is a Expires, last Modified, and Cache-control:max-age set so as to have an expiration after one second. Internet Explorer does not have this problem.
I wonder if you, as experts of this domain, might know why, and how to prevent this apparently abnormal behavior?
Thanks a lot!
Here is a sample html page which doesn’t reload properly with firefox, but does with IE:
function clearbg(){
document.getElementById(”myframe”).style.background=”none”;
document.getElementById(”mypic”).src=”";
setTimeout(”setbg()”,1000);
}
function setbg(){
document.getElementById(”myframe”).style.background=”url(’http://www.sytadin.equipement.gouv.fr/tempsreel/parisint.gif’)”;
document.getElementById(”mypic”).src=”http://www.sytadin.equipement.gouv.fr/tempsreel/parisint.gif”;
setTimeout(”clearbg()”,1000);
}
yannack,
You cannot prevent caching in Firefox. Using no-store does force the use of the in-memory cache, but it only affects the reload of pages - not embedded resources such as images.
The only way we know to force an image reload in Firefox is to use a varying query string on the URL. We used a random number on the end of the image URL in this sample:
http://www.httpwatch.com/httpgallery/headers/
Thanks for your answer. That is what I suspected, sadly :( I knew about the varying URL trick, but this is not a valid option for me, for two reasons:
- I do not have control over most images, and some refuse to show if a parameter is added to the URL
- I don’t want FF to reload cached images which are still valid. Many images never change, in fact, it is the case most of the time. I don’t want to add useless traffic, I just want expired images to reload.
I guess it’s just “too bad for me” :(
Thanks again for your answer though!
Yannack
Informative, thank you :)
Hi, Can you do a blog post on the behaviour of IE/Firefox when they receive responses with no Expires header but with Cache-Control. Also, how would the behaviour change when requests go through a proxy cache such as Squid which returns responses as HTTP 1.0
Thank you, that was very helpful. I was wondering how Firefox chose an expiration time when the headers had none.
I have the reverse problem
Fire Fox seems to do a piss-poor job of caching web pages and typically takes for-freaking ever to reload images even from web sites I have visited 2 times, 10 times, 100 times before. It still takes forever to reload the same images it has already loaded at a previous visit. This is even after the cache size is set to maximum. 1662031 Megs
IE on the other hand loads previously visited web sites and images in a snap.
It is for this reason I only use IE for graphics intensive web sites.
I am facing an issue to reload the previous page from cache on click of browser’s back button.
In my application I want the previous page should be reloaded from cache if user hits the Back button with in 15 minutes. After 15 mins it should give refresh warning.
I am trying it as :
response.setHeader(”Cache-Control”,”max-age=60″); //HTTP 1.1
response.setHeader(”Pragma”,”no-cache”); //HTTP 1.0
it doesn’t work !!
Any idea how to acheive that.
Anurag,
The back button reload doesn’t look at any cache expiration information. If the page is cached it is reloaded from the cache regardless of whether it is stale.
If you want control over what the user sees you’ll need to prevent caching to allow reloading from the server.
The previous page should come with old data and not the latest one. Hence on back button some how I have to get repload the previous page.
It is not neccessary to user the cache-control. If there is any some logic in your mind to solve it, it will be helpful.
I want to prevent back button after sign out I tried using cache-control:no cache , no store also I used expires with them but it didn’t work
is there any soln for this?
Asmaa,
You need to use ‘no-cache’ and ‘no-store’, not ‘no cache’ and ‘no store’
Two questions:
1. Anyone know if the Mozilla bug # 441751 has been integrated into Firefox 3.5? The bug says that it was fixed in moz1.9.1, but I’m not too familiar with their versioning these days.
I’m still seeing the “POST content retrievable via back, with no-cache set” problem in Firefox 3.5.5.
2. Surprisingly, the same problem is evident in IE8. Anyone know anything about that?
Could this be because the no-store directive isn’t set as well?
One Trackback
[...] http://blog.httpwatch.com/2008/10/15/two-important-differences-between-firefox-and-ie-caching/ 分类: Web, 技术 标签: 随机日志zz:Tomcat的中文乱码的经典解决方案开始学用SeleniumFirefox实现text-overflow:ellipsisVelocity的扩展宝船公园及公交游 评论 (0) Trackbacks (0) 发表评论 Trackback [...]