How to stop Internet Explorer from caching AJAX requests

I recently had to revisit the issue of IE’s default cache settings causing problems when making AJAX requests. Out-of-the-box, the cache setting is ‘Automatically’, where pages are only fetched from the server if the cached content is from an earlier day, old or from an earlier session.

This can be a nightmare to deal with, as you cannot ask all users of a web site to change their browser settings.

One workaround is to use a ‘cache buster’ parameter in your GET request. Something like this:

var urlToFetch ='whatever.php?randNum='+newDate().getTime();

This works very well, but can have drawbacks, depending on your server setup. For example, if your application server sits behind a caching layer, you wouldn’t want the URL to be different every time for idempotent requests, as the cached version would never get used, and so your application server would get a direct hit every time.

One way around this without using to parameters is to set the ‘Cache-Control’ response header to direct the browser how to cache the response.

The ‘Cache-Control’ header can have various values, one of which is ‘no-cache’. This tells the browser that it should not cache the response, so the next time the same URL is requested, new content will always be sent (as there is no previous version in the browser’s cache).

This is how we do it using Groovy:

response.addHeader"Cache-Control","max-age=0,no-cache,no-store"

So really, which method you use boils down to this: If you know that the cache buster will have a performance hit on your setup, then don’t use it, otherwise use whichever method you prefer.

Also, as a developer, I can highly recommend changing your IE cache settings to ‘Every visit to the page’.

Update 10/02/2008

We’re finding that with some of our automated testing, IE 7 still caches the odd file now and then. To get around this, we have modified our ‘Cache-Control’ header to include two non-standard properties, ‘post-check’ and ‘pre-check’, and added an ‘Expires’ header as well: