views:

780

answers:

6

It is a well known problem that IE caches too much of html, even when giving a Cache-Control: no-cache or Last-Modified header to everypage.

This behaiviour is really troubling when working with querystrings to get dynamic information, as IE considers it to be the same page (i.e.: http://example.com/?id=10) and serves the cached version.

I've solved it adding either a random number or a timestring to the querystring (as others have done) like this http://example.com/?id=10&t=2009-08-06_13:12:56 that I just ignore serverside.

Is there a better option? Is there another, cleaner way to acomplish this? I'm aware that POST isn't cached, but it is semanticaly correct to use GET here.

A: 

I have the same problem, but take care, in one second there can be many requests. This is why I use this:

$.getJSON("http://server/example?param=value&dummy=" + Math.random(), ...);
FWH
Well, I don't want the **same client** hitting my server **several timer per second**, so I don't mind if the information showed is 1 second old. Of course, the output is plain text for humans.
voyager
A: 

Using a random number (not timestamp) on the querystring, or actually changing the filename are the two methods recommended. Steve Souders and YAHOO!'s performance group has published a ton of useful information and practices they've discovered and developed while optimizing one of the world's most heavily-visited properties.

Rex M
+1  A: 

You could also use the current Unix Time in milliseconds to avoid the problem of many requests in one second (it is much less likely to have multiple requests in one millisecond)

var url = "http://whatever.com/stuff?key=value&ie=" + (new Date()).getTime();
Sinan Taifour
A: 

Have you tried adding an ETag header in the response? You might use a random one, or a checksum of the generated page so that the cached version is served when appropriate.

I'm not sure what's the behaviour of IE, but with recent versions it should work.

See also the HTTP RFC section on ETag

filippo
A: 

So, in the end, the only reliable way to do this (thanks to IE6) is using a random, or time bound querystring.

You could use a time bound querystring that only changes every 15 seconds (or any other amount of time), so you'd lower the server hit count, as you'd see locally cached content for those 15 seconds.

If you have a standard compliant browser, you can get away with only using ETags.

voyager
This again will fail if the user comes back to the page using the back button and does a refresh on the page. Were you able to find a sure-shot solution which works in all cases? Thanks.
lostInTransit
You generate the "random" part of the querystring with javascript clientside like shown on http://stackoverflow.com/questions/1234246/random-querystring-to-avoid-ie-caching/1234260#1234260 That way, it will be different *every time* the `get` or `post` is done.
voyager
@voyager: " ...(thanks to IE6) is ..." thanks to IE7 too, I did not test IE8 yet.
Marco Demajo
A: 

Assuming you are using jQuery, instead of using $.get or $.getJson, use the more generic $.ajax and explicitly set the cache value to false. The following is an example:

$.ajax({
        url: "/Controller/Action",
        cache: false,
        type: "GET",
        dataType: "json",
        success: function(data, textStatus) {
                         alert("success");
                 }
    });

A little more code required (not much though) than using .getJson or .get but will solve the problem cleanly without appending random numbers.

Simon Fox