This section covers the most useful headers for caching purposes.
In the HTTP1.1 specification, servers should send a no-cache response for cache-control headers to indicate that the content should not be cached. Both client and server side caches should honor this header to prevent caching of the dynamic content that such headers signify. Most development languages support the headers to control response header values.
On the other hand, you can allow caching by returning a server response of public for the cache-control header (absence of the cache-control header can also indicate that the object can be cached). A cache-control header value of private is a special case, meaning that the browser may cache the object locally, but proxy servers should not cache it.
The request-response flow in Figure 4 shows how Google instructs the proxy servers not to cache by using the cache-control header.
Finally, when the server responds with an expires header containing a date/time stamp that expires in the future, browsers can reuse the cached object until the expiration date (see Figure 5).
|Figure 5. Expiring Content: Google's Gmail server returns an expires header containing the date and time that the cached page should expire.|
As you can verify, here Gmail responds that the browser can reuse the cached Gmail home page until the date and time specified in the expires header.
Using the Last-Modified Header
Browsers use this header to determine the validity of a cached object's lifetime. When the browser requests this object, the server responds with a last-modified header containing a timestamp specifying when the object was last modified. The next time the user requests the same object, if the current timestamp exceeds the lifespan of the object, or if the user requested a page refresh, the browser sends an if modified since request to the server to determine whether the object has changed. If it has, browser sends a full GET request to fetch the new object and cache it again; otherwise, the browser delivers the object from its cache and updates the last-modified value on the object. Figure 6 shows a working example:
Here, when the browser requests www.yahoo.com, the server responds with a last-modified timestamp. Compare that to the behavior when the page is requested again with an if-modified-since header (see Figure 7), using the timestamp from the last-modified header.
|Figure 7. Checking for Modifications: By sending the if-modified-since header, the server will respond with a value indicating whether the content has been modified since the specified timestamp.|
In Figure 7, the browser sent a request with the if-modified-since header and the server responded with a 304 code, meaning that the browser can use the cached copy rather than doing a full GET from the server again.
To completely understand the effect of these headers, it's best if you experiment yourself, using a variety of header combinations to see the behavior. A good tool for analyzing headers is Wfetch.