抹桥的博客
Language
Home
Archive
About
GitHub
Language
主题色
250
952 words
5 minutes
HTTP Caching

I unexpectedly received an interview invitation from Alibaba DingTalk’s frontend team this afternoon, which made me quite happy. The interview covered everything from projects I’ve worked on to technologies I’ve used like Angular, React, and Express, making me realize my understanding isn’t deep enough. For example, I mentioned I like React and that large projects require Redux for data management. Then I was asked what problems Redux actually solves, and I couldn’t answer clearly. Overall, though, I felt pretty good about the first part of the interview.

But towards the end, the interviewer asked a rather fundamental question: “How do you control caching in the HTTP protocol?” I was stumped; I rarely encounter this in my daily work. I could only guess, mentioning changing filenames and setting relevant parameters in HTTP headers, but I couldn’t explain the specifics of how to set them or what content to include. I felt certain I’d fail at this point. But as the saying goes, one shouldn’t stumble twice in the same place. I’m writing this article to document the relevant aspects of HTTP caching.

Overview#

HTTP caching is primarily controlled in the following ways:

  1. Expires
  2. Cache-Control
  3. Last-Modified/If-Modified-Since
  4. ETag/If-None-Match

Let’s explore each one in detail.

Expires#

Expiration time, somewhat similar to Expires in cookies. You can set a specific expiration time in the header. Within this period, the browser will not request the file from the server; it will read it directly from the local cache. 1 The image above shows the HTTP header for a JavaScript file on my blog. As you can see, the Expires field (red box 1) is set to 4 hours after the current date. This means that, under normal circumstances, requests for this file before the Expires timestamp will directly use the local cache instead of re-fetching from the server. It’s important to note that Expires is an HTTP 1.0 feature. Most browsers now default to HTTP 1.1, so using Expires to control caching is not the preferred method.

Cache-Control#

Cache-Control and Expires serve essentially the same purpose: to indicate the validity period of the current resource, thereby controlling whether the browser uses a local cache or re-fetches the resource from the server. However, Cache-Control offers more granular control, and when both Expires and Cache-Control are present in the header, Cache-Control takes precedence.

The Cache-Control HTTP header can have values such as public, private, no-cache, no-store, no-transform, must-revalidate, proxy-revalidate, max-age. The directives in each message have the following meanings:

Public      indicates that the response can be cached by any cache.
Private     indicates that the entire or partial response message for a single user cannot be handled by a shared cache. This allows the server to describe only a portion of the response message for the user, and this response message is invalid for other users' requests.
no-cache    indicates that the request or response message should not be cached.
no-store    is used to prevent sensitive information from being inadvertently published. Sending this in a request message will prevent both the request and response messages from using a cache.
**max-age**   **indicates that the client can accept a response whose freshness lifetime is not greater than the specified time (in seconds).**
min-fresh   indicates that the client can accept a response whose freshness lifetime is less than the current time plus the specified time.
max-stale   indicates that the client can accept a response message that has exceeded its expiration period. If a max-stale value is specified, the client can accept a response message that is within the specified value beyond the expiration period.

2 As shown, the Cache-Control field (red box 2) has a value of public, max-age=14400. This means its validity period is 14400 seconds, or 4 hours, which is the same as the Expires time above. However, unlike Expires, it doesn’t require a specific timestamp like Mon, 07 Mar 2016 17:14:33 GMT; it only needs a maximum age. This is likely a more commonly used method.

Last-Modified/If-Modified-Since#

  1. Last-Modified indicates the last modification time of a resource. When responding to a request, the server tells the browser this resource’s last modification time.
  2. If-Modified-Since: When sending an HTTP request, the browser sends the last modification time of the cached resource to the server. The server compares this time with the actual file’s last modification time on the server. If the times match, it returns an HTTP status code 304, and the browser displays the cached file directly. If the times do not match, it returns an HTTP status code 200 and the new file content. The browser then discards the old local file, caches the new one, and displays it. It’s important to note that Last-Modified/If-Modified-Since must be used in conjunction with Cache-Control. Only when the local resource has expired (i.e., exceeded the time defined by max-age) will the browser send a corresponding request with If-Modified-Since to the server.

ETag/If-None-Match#

  1. ETag/If-None-Match also needs to be used in conjunction with Cache-Control.
  2. ETag: When the server responds to a browser request, it tells the browser the unique identifier for the current resource on the server; the server determines the identification rules. If-None-Match: When a resource expires (i.e., exceeds the time defined by max-age) and is found to have an ETag declaration, the browser includes If-None-Match (i.e., the ETag value of the locally cached resource) when sending a subsequent request to the server. If the server receives a request with If-None-Match, it compares it with the ETag of the requested resource on the server. If they are the same, it indicates no change to the resource and returns 304; otherwise, it returns 200 and the new resource.

The priority of these four methods can be illustrated with a diagram: 3 Image from As you can see, ETag has a higher priority than Last-Modified.

Reference Articles:

  1. Browser Caching Mechanism
  2. Introduction to Browser Cache-Related HTTP Headers: Expires, Cache-Control, Last-Modified, ETag
  3. HTTP Request Header Tag If-Modified-Since

This article was published on March 8, 2016 and last updated on March 8, 2016, 3499 days ago. The content may be outdated.

HTTP Caching
https://blog.kisnows.com/en-US/2016/03/08/http-cache/
Author
Kisnows
Published at
2016-03-08
License
CC BY-NC-ND 4.0