[A self-reflection on whether National strong belongs to hazardous waste caused by what 304 is]

Village head bully two dog son: “the country is strong, you say 304 is what, so simple, this can’t?”

Not deep silly country strong: “this problem I will, easy!”


1. The definition of 304

One sentence definition: Not Modified (the server side resource is Not changed, so the client side cache can be used directly)

In the Diagram of HTTP, 304 is explained as follows: “This status code indicates that when the client sends a conditional request, the server allows the request to access the resource, but directly returns 304 when the request does not meet the condition. 304 The status code does not contain any response body (the header does not contain the body, which reduces the packet size and improves transmission efficiency). 304 is classified in 3XX, but has nothing to do with redirection.”

The explanation says: “If the request does not meet the condition, return directly to 304.” So what do we mean by “unmet condition”?

After the browser first sends a request to the server, the server puts last-Modified in the response header to indicate that the resource is cached to the client. If a client requests another file and finds that the cached file has last-Modified, the request header carries the if-Modified-since field, which is the last-modified value of the cached file. In this case, the server can determine whether to return 304 or 200 by determining the value of if-modified-since and the time when the resource was last Modified.

At this point you may ask, every time to ask the server whether the cache has expired, it is too much food? This brings us to another topic: strong and negotiated caches


2. Strong caching and negotiated caching

In one sentence: when the browser is ready to make a request to the server, it first verifies that the strong cache is available and then uses it if it is available (the request still returns the 200 status, but there is no interaction with the server). Otherwise, the protocol cache is entered, that is, HTTP requests are sent.

1. Strong cache

In the strong cache phase, HTTP requests do not need to be sent. In this phase, only the response header field of the last request is judged. If the resource is still available, the cache resource is directly reused.

In the HTTP/1.0 era, Expires was used, whereas HTTP/1.1 used cache-control.

1.1 Expires

The request header carries an Expires field that indicates when the resource has expired, and the next time a request is made, you simply need to compare the current time to Expires to know if the cache is available

Expires: Wed, 22 Nov 2019 08:41:00 GMT
Copy the code

One problem with Expires is that it is compared to the client time, so there can be client and server time inconsistencies. This method was deprecated in HTTP/1.1

1.2 Cache-Control

In HTTP1.1, a very critical field is adopted: cache-control. This field also exists in the response header returned by the server.

The fundamental difference with Expires is that it doesn’t use a “specific expiration point,” but rather an expiration period to control the cache. The corresponding field is max-age. Such as:

Cache-control :max-age=3600Copy the code

In addition to max-age, it has other properties:

  • Public: indicates that both client and proxy servers can cache. Because typically a request may go through different proxy servers before reaching the target server, the result is that not only the browser can cache the data, but any proxy node in between can cache the data
  • Private: In this case, only the browser can cache, the intermediate proxy server can not cache
  • No-cache: skips the current strong cache and sends HTTP requests to enter the negotiation cache
  • No-store: does not cache in any form
  • S-maxage: This is similar to max-age, but the difference is that s-maxage is the cache time for the proxy server
  • Must-revalidate: This field is added once the cache expires. You have to go back to the source server for validation (because the HTTP specification allows clients to use expired caching directly in special cases, such as when a request fails to be validated, or when special instructions are configured (stale-while-revalidate,stale-if-errorEtc.)

When both Expires and cache-control are present, cache-control takes precedence

When the strong cache fails, the next stage is negotiated cache

2. Negotiate cache

When the strong cache fails, a request is sent to the server. In addition to the initial request, subsequent requests carry a cache tag in the request header to verify that the client cache is available

There are roughly two types of cache tags: Last-Modified and ETag

2.1 Last-Modified

When a client sends a request for the first time, the server puts last-Modified in the response header. This field indicates when the resource was Last Modified. When the client requests again, the request header is marked with the if-Modified-since field, which is the last-modified value returned from the Last request

If modified-since = If modified-since = If modified-since = If modified-since = If modified-since = If modified-since = If modified-since

  • If the if-modified-since value is less than the time when the server resource was last Modified, the resource has been updated. The latest resource is now returned with the latest modification time
  • Otherwise, 304 is returned to tell the client that the cache is available
2.2 the ETag

ETag generates an identifier (similar to a file hash) based on the content of a file and uses this identifier as the basis for whether a file resource is updated.

The client receives the value of ETag and sends it to the server as if-none-match in the request header on the next request.

If the server receives if-none-match, it compares it with the ETag of the resource on the server:

  • If they are different, it’s time for an update. The server returns a new resource, just as it does with a regular HTTP request response
  • Otherwise, 304 is returned to tell the client that the cache is available
2.3 Comparison between the Two
  • ETag is superior to Last-Modified in accuracy. Because ETag identifies resources by content, changes in resources can be accurately sensed. Last-modified, on the other hand, does not accurately perceive resource changes in some special cases. There are two main cases:

    • Editing a resource file without changing its contents also causes a cache failure
    • Last-modified is perceived in seconds, and if the file changes multiple times within a second, then last-Modified does not reflect the change
  • Last-modified is superior to Etag in terms of performance for the simple reason that last-Modified only records a point in time, whereas Etag needs to generate hashes based on the contents of the file

  • In addition, if both approaches are supported, the server will prioritize ETag