11

I am having an issue with ajax caching, This was a problem in IE browser too but i fixed it by Writing the Following code.

    response.setHeader("Cache-Control", "no-cache");
    response.setHeader("expires","-1");
    response.setHeader("pragma","no-cache");

But I see Safari4.0 on MAC is Caching the Ajax request(We have a requirment to support this). Fire Fox never a problem. Regarding this "Expire" i am setting it to -1, i see lot of places it is set 0 or some old date from past. Will it make a difference?

sideshowbarker
  • 81,827
  • 26
  • 193
  • 197
pushya
  • 4,338
  • 10
  • 45
  • 54

3 Answers3

13

Send an extra parameter with your GET request that will never be the same, for example, the current timestamp. Something like:

url = url + '&nocache=' + new Date().getTime();

This will prevent caching.

Ry-
  • 218,210
  • 55
  • 464
  • 476
  • 6
    While this will work, it is a hack -- I'd like to know why Safari is apparently ignoring headers and inappropriately caching things. – josh3736 Mar 30 '12 at 18:33
  • @josh3736: I don't know. Could be part of the fact that the variable is `response` and the headers should probably be set on `request` using `setRequestHeader`. But this is the "industry-standard" way to prevent caching, it's much less of a hack than setting headers :) – Ry- Mar 30 '12 at 18:35
  • @ minitech We are setting the new date().getTime();. We are using our own ajax library in that i see we are doing it. this.get = function(queryString) { m_requestId = new Date().getTime(); m_request.open("GET", queryString, true); m_request.send(null); return m_requestId; }; – pushya Mar 30 '12 at 18:39
  • @minitech I would hardly say setting headers is a hack. Setting a header is the appropriate way to handle the cache - the date trick is used because of IEs aggressive ajax caching. – Snuffleupagus Mar 30 '12 at 18:40
  • 1
    I assumed the `response.setHeader` calls were *server* code, where we would be setting response headers. Regarding headers vs. cache-busting parameter, you're actually backwards: HTTP headers are the proper, RFC-specified place to control client and proxy caching. Cache-busting querystring parameters are just a commonly-used hack that rely on side effects rather than standards. – josh3736 Mar 30 '12 at 18:42
3

First, a note on your Expires header. Your question doesn't specify what server framework you're using, so I'm not sure if this is applicable. However, it looks like you might be sending an invalid Expires header.

The RFC requires Expires to be a date, however you appear to be setting the header to a literal "-1". There are many frameworks that have an expires property on their HTTP response object that takes an int and automatically calculates a date that is that number of seconds from now.

Use a HTTP inspector to ensure that your server is sending a validly formatted date and not -1 in the Expires header.


You might try making your Cache-Control header more restrictive:

response.setHeader("Cache-Control", "private, no-cache, no-store, must-revalidate");

must-revalidate tells caches that they must obey any freshness information you give them. HTTP allows caches to serve stale representations under special conditions; by specifying this header, you’re telling the cache that you want it to strictly follow your rules. [1]

josh3736
  • 139,160
  • 33
  • 216
  • 263
1

According to RFC 2616 section 9.5 about POST

   Responses to this method are not cacheable, unless the response
   includes appropriate Cache-Control or Expires header fields. However,
   the 303 (See Other) response can be used to direct the user agent to
   retrieve a cacheable resource.

So, the browser must not cache POST responses, unless the response specifies otherwise. In the same time, browsers may cache GET responses, unless the response specifies otherwise. So, for the requests that should not be cached, such as AJAX requests, POST is preferrable method.

If you, for any reason, don't want to use POSTs for AJAX, you should use the trick mentioned by minitech, it is in fact widely used to force browser to load current version of any resource.

Danubian Sailor
  • 1
  • 38
  • 145
  • 223