Download and Buy Now Link

Two Important Differences between Firefox and IE Caching

October 15, 2008

When you setup a web server there are generally two types of caching that you need to configure:

  1. HTML resources are expired immediately so that any changes made to a site are quickly picked up by existing users.
  2. 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-Modified response 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:

no-store and no-cache headers

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 Expires header. 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

27 Comments

  • 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

  • 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.

  • Pingback: OnlyLonely & Marshall’s » IE add cache-control:no-cache to 302 redirect

  • 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?

  • 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?

  • Hi,

    Please note: As per the HTTP 1.1 specifications, the ‘no-cache’ directive DOES NOT say that no caching should be done. It says that if ‘no-cache’ is included then the client should ALWAYS REVALIDATE with the origin server before showing a persisted version of the data. Hence ‘no-cache’ means cache but always validate before showing to ensure that only the latest version is being shown.

    The ‘no-store’ directive on the other hand states that NOTHING should be STORED. Hence it means, dont cache and always download from server.

    I am not familiar with the back button issue, but as far as normal caching is concerned it is IE which at fault and not Firefox because IE does not cache at all with the ‘no-cache’ directive and always gets a fresh copy from the server which is actually wrong. This should only be done with the ‘no-store’ directive.

  • To clarify: when the user is using “back” button in Firefox to return to the page that had no-cache directive, and Firefox does not revalidate it with the server, it’s not seen as a bug by Firefox developers, but rather, the matter of terminology. Their point is that caching is what is being used for subsequent intentional visits to the page, such as when you type the same URL again and press Enter; but pressing “back” is related to viewing the history, so no-cache directive does not apply. That’s the outcome of the discussion at https://bugzilla.mozilla.org/show_bug.cgi?id=441751 says. Opera behaves in the same way.

    In other words, Firefox and Opera treat “back” as the desire to review the same already-seen contents, rather than revisiting the same URL.

  • In order to enforce the NO caching PHP session_start fucntion pulls out all these headers:

    Expires: Thu, 19 Nov 1981 08:52:00 GMT

    Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

    Pragma: no-cache

    I would reccomend anyone who does not want to cache a page to either use a session or anyway to send to browser the same headers show above.

  • If you are using struts than use following :

    and if you want to block it in specific action than use following :

    response.setHeader(
    “Cache-Control”,
    “no-cache, max-age=0, must-revalidate, no-store”);

  • Hello every one

    During my testing one page getting cached in IE but not in Firefox.Please let me know the reason.
    Any replays for this is appreciable.