I'm using Chrome 40 (so something nice and modern).
Cache-Control: max-age=0, no-cache
is set on all pages - so I expect the browser to only use something from its cache if it has first checked with the server and gotten a 304 Not Modified
response.
However on pressing the back button the browser merrily hits its own cache without checking with the server.
If I open the same page, as I reached with the back button, in a new tab then it does check with the server (and gets a 303 See Other
response as things have changed).
See the screen captures below showing the output for the two different cases from the Network tab of the Chrome Developer Tools.
I thought I could use max-age=0, no-cache
as a lighter weight alternative to no-store
where I don't want users seeing stale data via the back button (but where the data is non-valuable and so can be cached).
My understanding of no-cache
(see here and here on SO) is that the browser must always revalidate all responses. So why doesn't Chrome do this when using the back button?
Is no-store
the only option?
200
response (from cache) on pressing back button:
303
response on requesting the same page in a new tab:
Looks like this is a known 'quirk' in Chrome with using the back button. There is a good discussion of the issue in the bug report for it here:
https://code.google.com/p/chromium/issues/detail?id=28035
Sadly it looks like most people reverted to using no-store instead.
I expect though that most users are used to an experience of not getting a full page refresh using the back button. If you think about most Angular or Backbone apps that manage the back action themselves so that you just refresh content and not the page. With this in mind I suspect that having the customer refresh or get updates when they come back might not be that unexpected.
From http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1
Other than the name implies,
no-cache
does not require that the response must not be stored in cache. It only specifies that the cached response must not be reused to serve a subsequent request without re-validating, so it's a shorthand formust-revalidate, max-age=0
.It is up to the browser what to qualify as a subsequent request, and to my understanding using the back-button does not. This behavior varies between different browser engines.
no-store
forbids the use of the cached response for all requests, not only for subsequent ones.Note that even with
no-store
, the RFC actually permits the client to store the response for use in history buffers. That means client may still use a cached response even whenno-store
has been specified.Latter behavior covers cases where the page has been recorded with its original page title in the browser history. Another use case is the behavior of various mobile browsers which will not discard the previous page until the following page has fully loaded as the user might want to abort.
For clarification on the the behavior of the back button: It is not subject to any cache header, according to http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html#sec13.13
That means that disrespecting any cache control headers when using the back button is the recommended behavior. If your browser happens to honor a backdated expiration date or applies the
no-store
directive not only to the browser cache but also to the history, it's actually already departing from that recommendation.For how to solve it:
You can't, and you are not supposed to. If the user is returning to a previously visited page, most browsers will even try to restore the viewport. You may use deferred mechanism like AJAX to refresh content if this was the original behavior before the user left the page, but otherwise you should not even modify the content.
Have you tried using the full old set of no-cache headers?
This seems to work all the time, unless you are running a "pushState" web.