The Cache-Control
response header is the standard caching mechanism for modern HTTP. It can have multiple values, which are comma-separated.
no-store
: the browser cannot cache the response, everno-cache
: the browser must check with the server before assuming that the resource is still valid.
On successful ETag validation, it can skip downloading the resource again, but still requires a request to the server.
private
: the resource can be cached by the browser, but not at any higher levels, e.g., a CDN.public
: the resource can be cached. Redundant if given other arguments, like max-age
max-age
: specifies the number of seconds that the resource can be cached.The ETag
response header is used to uniquely identify a potentially cached resource. As far as I can tell, this is only used when the max-age
time has been exceeded. I.e., the browser doesn’t even have to check with the server, hoping for an HTTP 304 “Not Modified”, until after max-age
seconds have elapsed since it originally received the resource. After that time period elapses, though, it will send the same HTTP GET, but with an If-None-Match
request header, setting the header’s value to the ETag it originally received.
If the server is smart, it will check the received ETag against some hash or modification timestamp of the requested resource, and return an HTTP 304 with no body. But that seems a lot more complicated than a simple max-age
value. And it makes more since when serving static files rather than records from a database.