On our server, we have configured http response headers as follows:

Cache-Control:max-age=28800, must-revalidate   # (8 hours)
Date:Wed, 24 Apr 2013 21:36:19 GMT
Expires:Thu, 25 Apr 2013 05:36:19 GMT          # (8 hours from access)
Keep-Alive:timeout=15, max=484

Our intent was for the resource to be cached by the browser for 8 hours, after which the browser should check if it has been modified (with a 304 request) before using the cached copy.

However, I have found that the browser always makes a 304. (It continues to used it's cached copy, but checks the server for modifications before doing so - which I want to occur after 8 hours, not all the time.)

As I thought it should work, Cache-Control:max-age=28800, must-revalidate should instruct the client to use the cached resource until it reaches max-age in the cache, after which it must-revalidate with the origin server. I believe that the Expires directive is more of a fallback and that Cache-Control supersedes is - but if it were at play, I would expect the browser to use the cached copy until the expiration date, then fetch a new copy. Most of that is gleaned from this writeup, and perusing the spec a little.

Obviously, my understanding is incomplete - what am I missing?

EDIT: I mistakenly assumed that by refreshing the current page I would be testing what happens when the browser goes to subsequent pages that have the same resources linked. I was wrong - hitting the "refresh" button generally seems to force the browser to check if any of the resources have been modified before using the cached copies, which makes insanely obvious sense. When I click through to other pages, the resources are pulled directly from cache as expected.

  • Did you hit the browser's reload button? Apr 24 '13 at 22:15
  • Yes. I clear the cache and load the page. On the first load the resource is fetched as you'd expect. Reloading the page causes the browser to make the 304's. Apr 25 '13 at 1:48
  • That's what it's supposed to do! Try browsing around the site instead. Apr 25 '13 at 2:07
  • I am not sure I follow. Perhaps a concrete example would help. Every page in the site references main.css. Regardless of which page I load, the browser makes a conditional GET for main.css when it already has a cached copy, the max-age (cache-control directive) has not been reached, and the expiration date is still eight hours away. Shouldn't the browser use the cached local copy instead of making conditional GETs? Why is it checking to see if the resource has been modified? (How can I instruct it not to?) Apr 25 '13 at 2:33
  • Realizing my first comment may have thrown you off. To be clear, I emptied the cache at the outset to start with a clean slate, but all subsequent reloads were with a full cache. Apr 25 '13 at 2:36

This is desired behavior specifically for the browser reload button. The reload button will attempt to validate the page, and some content like CSS.

There's other ways to load your page, like navigating away and back. Or click on the URL bar and click "enter" in those cases, the browser will go with the cached data without revalidating.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.