HTTP caching headers
Cache-control
The Cache-control
header can have one of three values:
public
: public proxy servers can cache the response. Suitable for resources that can be shared between multiple users (e.g., home page logo or website icons).private
: only the browser can cache the response. Suitable for user-specific content (e.g., HTML page showing user’s images).no-store
: nobody should cache the response because it contains sensitive information that shouldn’t be persisted in memory.
A server can also specify a max-age
value in the Cache-control
header. This tells clients the number of seconds to cache the response.
HTTP/1.1 200 OK
Last-Modified: Wed, 25 Jan 2012 17:55:15 GMT
Expires: Sat, 22 Jan 2022 17:55:15 GMT
Cache-Control: max-age=315360000,public
max-age
Cache-Control: max-age=604800
Specifies that the response is fresh until X seconds after the response was generated so caches can store and reuse this response for subsequent requests whilst it’s fresh.
If-Modified-Since
If-Modified-Since
can be used by clients to check if a cache is still valid.
GET http://… HTTP/1.1
If-Modified-Since: Wed, 25 Jan 2012 17:55:15 GMT
This tells a server that the client only needs the full response if the cache is stale. If the cache is still valid, the server responds with:
HTTP/1.1 304 Not Modified
Expires: Sat, 22 Jan 2022 17:16:19 GMT
Cache-Control: max-age=315360000,public
This tells the client it can still use its cache.
ETag
The ETag
is usually computed (using a hash function) from the resource’s contents or a version number determined from the file name. If the resource changes, the server generates a new ETag
. Clients can check if the ETag
of a response matches an existing cache entry. If so, the cache is still valid, otherwise, it’s time to invalidate it.
For example, a response for an index.html
file might return the following:
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
ETag: "33a64df5"
Cache-Control: max-age=3600
<!doctype html>
…
If the response is stale, the client will take the value of the ETag
response header for the cache response, and set it in the If-None-Match
request header to ask the server if the cached resource has been modified:
GET /index.html HTTP/1.1
Host: example.com
Accept: text/html
If-None-Match: "33a64df5"
The server will check the latest ETag of index.html
(using whatever hashing / version number mechanism it uses) and return a 304 Not Modified
response if it’s still the same. If it’s different, it will return a new ETag
response header and with a 200 OK
response with the latest version of the resource.
HTTP/1.1 200 OK
Server: Apache
Last-Modified: Fri, 06 Jan 2012 18:08:20 GMT
ETag: "8e5bcd-59f-4b5dfef104d00"
Content-Type: text/xml
Vary: Accept-Encoding
Content-Encoding: gzip
Content-Length: 437
Vary
Indicates what parts of the request message influence the response content besides the method and URL. In practice, Vary
is used to create a cache key when content negotiation is in use. For example, if your web application supports multiple languages, you may specify:
Vary: Accept-Language
So that requests that contain the Accept-Language: en-US
have a separate cache entry to those with Accept-Language: ja-JP
. You wouldn’t want US visitors to receive the same response as Japanese visitors.
Another potential value is Accept-Encoding
for when you don’t cached gzip responses to be served to a client that doesn’t support gzipped-encoded responses.
Thanks for your comment 🙏. Once it's approved, it will appear here.
Leave a comment