a little madness

A man needs a little madness, or else he never dares cut the rope and be free -Nikos Kazantzakis

Zutubi

Ajax vs Caching vs Firefox 3

In an earlier post, many moons ago, I related some struggles with Ajax page updates and browser caching behaviour. Today I have had to revisit the same problem again, thanks to Firefox 3.

The good news is that this time it was very easy to spot via the “Net” tab of Firebug. I could clearly see that no request was being made when I expected an Ajax-based panel update. I could also see that the response headers on the previous request for the same panel, whilst including some Cache-Control parameters, didn’t seem to include every header I expected. A bit of searching around led me to a useful comment on a Mozilla bug report. The bug report suggests there may be some issues when specifying multiple Cache-Control headers, with a specific header ordering to fix the problem. So I updated the headers set to:

Cache-Control: no-store, no-cache, must-revalidate
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Pragma: no-cache

So far this update appears to work: at the very least it solves the panel update problem I was seeing. Hopefully it can save someone else wasted debugging time!

Liked this post? Share it!

8 Responses to “Ajax vs Caching vs Firefox 3”

  1. July 30th, 2008 at 10:33 am

    kL says:

    This looks bad. Very very bad, if you check RFC 2616. Try not abusing no-store and must-revalidate, because they have specific, important meaning and throwing them around puts pressure on browsers and proxies to ignore them (internet on the grand scale really needs cacheable things).

    You don’t seem to be expert on the subject, judging by the fact that you’ve seriously tried to use element for cache control.

    Cache-control: max-age=5 (it’s freshness time in seconds) sent by the server, and nothing sent by the client should do the trick.

  2. July 30th, 2008 at 10:46 am

    Jason says:

    Hi kL,

    > This looks bad. Very very bad, if you check RFC 2616. Try not abusing
    > no-store and must-revalidate, because they have specific, important
    > meaning and throwing them around puts pressure on browsers and
    > proxies to ignore them (internet on the grand scale really needs
    > cacheable things).

    Standards are a wonderful thing, but unfortunately we live in the Real World, where I need to make software that works in existing browsers. I can’t seriously be told that I am putting pressure on anyone by doing this. Yes, “the internet … needs cacheable things” – but perhaps I know my own application and know when caching is actually the wrong behaviour?

    > You don’t seem to be expert on the subject, judging by the fact that
    > you’ve seriously tried to use element for cache control.

    I am no expert, nor did I claim to be. However I do have some practical experience of what works and what doesn’t, and so far this is the best solution I have found.

    > Cache-control: max-age=5 (it’s freshness time in seconds) sent by the
    > server, and nothing sent by the client should do the trick.

    This won’t “do the trick” for at least two reasons:

    1) As stated in my previous post, which I linked to, going back is also an issue, and AFAIK to solve it you must prevent the page from getting into the cache. Funnily enough, this is because of how the standards define the behaviour of the back button.
    2) 5 seconds is a complete fudge, as would be 1 second (even though less risky in practice). The updates to these panels happen because something has changed, loading them from the cache is never the correct behaviour.

    Did you even try to understand the use case I am talking about? Have you *tried* it in real life? Criticism is fine, but not when it is unecessarily agressive and plain wrong for the case I have discussed.

  3. July 31st, 2008 at 2:37 am

    Nicholas says:

    I kept hitting this issue and rather than messing with cache configuration headers, I simply appended a parameter on the end of the (GET) URL using the javascript provided time in ms. That way, each url is unique and will never be read from cache. Hopefully your server side will gracefully ignore the unexpected extra parameter.

  4. July 31st, 2008 at 4:28 am

    Jason says:

    Hi Nicholas,

    Thanks for the comment – I should have mentioned this technique as it can also be very effective. It does have the benefit of being easier than trying to debug caching behaviour, where what you see can be deceiving. I have even noticed that some of the JavaScript libraries have built in support for adding a timestamp parameter to Ajax requests.

  5. August 18th, 2008 at 6:54 am

    Code Swimming » Firefox Caching Bug says:

    [...] order, otherwise it will cache it even if the headers correctly specify not to.  More info here and [...]

  6. September 13th, 2008 at 4:53 am

    AndrewSeven says:

    KL: Pleas go tell the people devloping FireFox3 about the standard.

    FF2 IE Safari and Chrome all respect the expiration date, but FF3 seems to need to be told explicity to recheck.

  7. January 14th, 2009 at 3:00 am

    Randyshaw says:

    I have been using the timestamp in ms for years in my Ajax, but FF3 doesn’t seem to be respecting it. My Ajax stopped working as soon as I upgraded to FF3, but it works in IE and Safari…
    Any other ideas?

  8. April 23rd, 2009 at 6:47 pm

    A grateful developer says:

    Thank you very much for this post, especially the code excerpt.
    Been debugging this issue for hours and searching some explanations on the internet.

    Finally, solved by copying the code above to my php script.

    Thank you very much.

    What a day (in a developer life).

Leave a Reply