HTTP caching is optional, but reusing a cached resource is usually desirable. However, common HTTP caches are typically limited to caching responses to
GET and may decline other methods. The primary cache key consists of the request method and target URI (oftentimes only the URI is used as only GET requests are caching targets). Common forms of caching entries are:
- Successful results of a retrieval request: a
200(OK) response to a
GETrequest containing a resource like HTML documents, images or files.
- Permanent redirects: a
301(Moved Permanently) response.
- Error responses: a
404(Not Found) result page.
- Incomplete results: a
206(Partial Content) response.
- Responses other than
GETif something suitable for use as a cache key is defined.
A cache entry might also consist of multiple stored responses differentiated by a secondary key, if the request is target of content negotiation. For more details see the information about the Vary (en-US) header below.
Cache-Control: private Cache-Control: public
Pragma (en-US) 是HTTP/1.0的檔頭欄位，此檔頭欄位沒有特別指是HTTP回覆怎麼處理，所以用此來取代HTTP/1.1
Once a resource is stored in a cache, it could theoretically be served by the cache forever. Caches have finite storage so items are periodically removed from storage. This process is called cache eviction. On the other side, some resources may change on the server so the cache should be updated. As HTTP is a client-server protocol, servers can't contact caches and clients when a resource changes; they have to communicate an expiration time for the resource. Before this expiration time, the resource is fresh; after the expiration time, the resource is stale. Eviction algorithms often privilege fresh resources over stale resources. Note that a stale resource is not evicted or ignored; when the cache receives a request for a stale resource, it forwards this request with a If-None-Match (en-US) to check if it is in fact still fresh. If so, the server returns a 304 (en-US) (Not Modified) header without sending the body of the requested resource, saving some bandwidth.
Here is an example of this process with a shared cache proxy:
The freshness lifetime is calculated based on several headers. If a "
Cache-control: max-age=N" header is specified, then the freshness lifetime is equal to N. If this header is not present, which is very often the case, it is checked if an Expires (en-US) header is present. If an
Expires header exists, then its value minus the value of the
Date header determines the freshness lifetime. Finally, if neither header is present, look for a Last-Modified (en-US) header. If this header is present, then the cache's freshness lifetime is equal to the value of the
Date header minus the value of the
Last-modified header divided by 10.
The expiration time is computed as follows:
expirationTime = responseTime + freshnessLifetime - currentAge
responseTime is the time at which the response was received according to the browser.
Web developers invented a technique that Steve Souders called revving. Infrequently updated files are named in specific way: in their URL, usually in the filename, a revision (or version) number is added. That way each new revision of this resource is considered as a resource on its own that never changes and that can have an expiration time very far in the future, usually one year or even more. In order to have the new versions, all the links to them must be changed, that is the drawback of this method: additional complexity that is usually taken care of by the tool chain used by Web developers. When the infrequently variable resources change they induce an additional change to often variable resources. When these are read, the new versions of the others are also read.
This technique has an additional benefit: updating two cached resources at the same time will not lead to the situation where the out-dated version of one resource is used in combination with the new version of the other one. This is very important when web sites have CSS stylesheets or JS scripts that have mutual dependencies, i.e., they depend on each other because they refer to the same HTML elements.
The revision version added to revved resources doesn't need to be a classical revision string like 1.1.3, or even a monotonously growing suite of number. It can be anything that prevent collisions, like a hash or a date.
When a cached document's expiration time has been reached, it is either validated or fetched again. Validation can only occur if the server provided either a strong validator or a weak validator.
Revalidation is triggered when the user presses the reload button. It is also triggered under normal browsing if the cached response includes the "
Cache-control: must-revalidate" header. Another factor is the cache validation preferences in the
Advanced->Cache preferences panel. There is an option to force a validation each time a document is loaded.
ETag response header is an opaque-to-the-useragent value that can be used as a strong validator. That means that a HTTP user-agent, such as the browser, does not know what this string represents and can't predict what its value would be. If the
ETag header was part of the response for a resource, the client can issue an If-None-Match (en-US) in the header of future requests – in order to validate the cached resource.
The Last-Modified (en-US) response header can be used as a weak validator. It is considered weak because it only has 1-second resolution. If the
Last-Modified header is present in a response, then the client can issue an If-Modified-Since (en-US) request header to validate the cached document.
When a validation request is made, the server can either ignore the validation request and response with a normal
OK, or it can return 304 (en-US)
Not Modified (with an empty body) to instruct the browser to use its cached copy. The latter response can also include headers that update the expiration time of the cached document.
The Vary (en-US) HTTP response header determines how to match future request headers to decide whether a cached response can be used rather than requesting a fresh one from the origin server.
When a cache receives a request that can be satisfied by a cached response that has a
Vary header field, it must not use that cached response unless all header fields as nominated by the
Vary header match in both the original (cached) request and the new request.
This can be useful for serving content dynamically, for example. When using the
Vary: User-Agent header, caching servers should consider the user agent when deciding whether to serve the page from cache. If you are serving different content to mobile users, it can help you to avoid that a cache may mistakenly serve a desktop version of your site to your mobile users. In addition, it can help Google and other search engines to discover the mobile version of a page, and might also tell them that no Cloaking is intended.
User-Agent header value is different ("varies") for mobile and desktop clients, caches will not be used to serve mobile content mistakenly to desktop users or vice versa.
- RFC 7234: Hypertext Transfer Protocol (HTTP/1.1): Caching
- Caching Tutorial – Mark Nottingham
- HTTP caching – Ilya Grigorik
- RedBot, a tool to check your cache-related HTTP headers.