When does a browser NOT make a request to the server for a file?
Expires: Tue, 19 Jan 2038 03:14:07 GMT
Firstly, the relevant HTTP spec is RFC 7234. If you look at the spec you will observe two things:
Secondly, you're doing nothing wrong on your end. Browsers are free to cache responses and use those cached responses given the headers you're returning. The key point is in Section 4, where it is noted that one of the conditions for serving a cached response is that the response is either:
fresh (see Section 4.2), or
allowed to be served stale (see Section 4.2.4), or
successfully validated (see Section 4.3).
Since you're spitting out an
Expires header that is far in the future, and that point in the future has not yet been reached, the response is 'fresh', and therefore revalidation is not required. So you're doing everything that the spec suggests you should be on your end. (Although using
Cache-Control: max-age=foo is a more modern way of setting cache expiry times than using the
So if you want to change the browsers' caching behaviour, you're out of luck.
However, things might not be as bad as you think. You're probably only be seeing a request and 304 because you're refreshing the page in your browser when testing. Browsers handle cached resources differently depending upon how the request for them was triggered.
I ran a simple test in which I created a HTML page that contained a
<script> tag pointing to a JS file, an
<img> tag pointing to an image, and a
<link> tag pointing to a CSS stylesheet. All of these files were hosted on an Apache server configured to serve them with:
Naturally, all resources were served with 200 codes on first page load. Thereafter, testing in Chrome or Firefox installs with default settings, I observed that:
This page indicates that Internet Explorer has the same behaviour:
There are a number of situations in which Internet Explorer needs to check whether a cached entry is valid:
- The cached entry has no expiration date and the content is being accessed for the first time in a browser session
- The cached entry has an expiration date but it has expired
- The user has requested a page update by clicking the Refresh button or pressing F5
In other words, you're usually only going to see these revalidation requests if the user explicitly refreshes the page. Unless you have some very particular requirements about how you want the browser cache to behave, this behaviour seems perfectly reasonable.
Google and Mozilla both have some documentation about HTTP caching (I can't find anything equivalent on MSDN or the Apple Developers site), but neither suggests the existence of any vendor-specific caching headers that can be used to modify the rules the browser uses to choose when to revalidate. What you want to do is simply not possible.