16

I'm wondering if there is a way how to detect when a response is returned from a local cache? Is it possible?

The solution should be general and work for unconditional requests. In this case, the response code is always 200 OK, but XHR returns a cached resource for the second request (e.g. the first response contains Expires header, so there is no need to ask a server for a new resource before the expiration date).

Filip
  • 3,002
  • 1
  • 26
  • 37
  • Doesn't sound possible. How about adding a timestamp to the response? – Wolfgang Stengel Oct 12 '12 at 21:12
  • I don't know, but Chrome Developer Tools is able to show the information; (Network pane, Size column - from cache) So I wonder how they do it ;) (Firebug for FF the same, Response Headers: From Cache) – Filip Oct 13 '12 at 10:16

3 Answers3

12

The answer is Date header

  • If date header is before send date then a response is coming from a cache.
  • If date header is after date when a request was sent then a response is fresh.

e.g.

  • from cache: request was sent at 11:00, response date is 10:59
  • no cache: request was sent at 11:00, response date is 11:01
Filip
  • 3,002
  • 1
  • 26
  • 37
  • @RichBradshaw I found general solution, finally. The answer is updated. – Filip Jun 12 '13 at 16:58
  • 1
    I tried this approach. It seemed promising... but it turns out that if your content is cached by Cloudfront, it will also have an old date on it, and then you cannot tell whether you retrieved the response from local browser cache or Cloudfront (other than by keeping an eye on network activity). – timday Oct 26 '21 at 16:36
1

Check to see if the status code returned is 304 (not modified) in the onreadystatechange function. Something along the lines of:

xmlhttp.onreadystatechange=function()
{
  if (xmlhttp.readyState==4 && xmlhttp.status==304)
    {
      alert("Cached");
    }
} 
Kevin Bowersox
  • 93,289
  • 19
  • 159
  • 189
  • Thank you @kmb385, but this solution works just in case of conditional request (If-*, e.g. If-Modified-Since, If-None-Match) and I'm looking for general solution. The question has been updated. – Filip Oct 11 '12 at 01:48
1

Apparently we can also use the Resource Timing API to determine whether something was served from browser cache; if the transferSize is 0 (and the encodedBodySize is >0) then that's a cache hit.

That seems like a better solution than the others, as long as you're dealing with a browser that supports it.

Ref: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceResourceTiming/transferSize

Tao
  • 13,457
  • 7
  • 65
  • 76