The web wouldn’t operate without caching. Between you and the server, there is a browser and any number of proxy servers which cache responses. Much of this is handled transparently by applications which dramatically reduce Internet traffic. However, it can also be the cause of bizarre web application quirkiness if you’re not very careful …
Set Your Headers
Caching is controlled by the HTTP status code and the
Cache-Control headers returned by every request. For subsequent requests to the same URL, the browser/proxy will either:
- retrieve the previous data from its own cache
- ask the server to verify whether the data has changed, or
- make a fresh request.
Cache-Control header primarily determines this action. It can set up to three comma-separated values:
nostore or nocache
nostore stops the browser and all proxy servers caching the returned data. Every request will therefore incur a trip back to the server.
The alternative is
nocache. The browser/proxy will make a server request and pass back
Last-Modified (date/time) and/or an
Etag (response hash/checksum) in the header. These are present on subsequent requests and, if the response has not changed, the server returns a
304 Not Modified status, which instructs the browser/proxy to use its own cached data. Otherwise, the new data is passed back with a
200 OK status.
public or private
public means the response is the same for everyone and the data can be cached in browser or proxy stores. It’s the default behavior, so it’s not necessary to set it.
private responses are intended for a single user. For example, the URL
https://myapp.com/messages returns a set of messages unique to each logged-in user, even though both of them use the same URL. Therefore, the browser can cache the response, but proxy server caching is not permitted.
This specifies the maximum time in seconds a response remains valid. For example,
max-age=60 indicates the browser/proxy can cache the data for one minute before making a new request.
Your server, language and framework often control these settings, so you rarely need to tinker — but you can. Presume you wanted to cache an individual user’s JSON response to an Ajax request for 30 seconds. In PHP:
or a Node.js/Express router:
Continue reading %How to Solve Caching Conundrums%