Another Intro for HTTP Cache


There are two different categories of HTTP caching. One is so-called Strong/Force Cache, whilst the other is called as Negotiation Cache.

Here’re the brief intro of those:

  1. Force Cache takes precedence over Negotiation Cache;
  2. Once Force Cache is hit, there is no need to interact with server-side;
  3. For Negotiation Cache, interacting with server-side is a must to determine whether the resource caching in the client-side is available.

Please Notice, Negotiation Cache is just like we are not sure something that is available or not, and after getting a big YES from authority, we can take it into use with no worry.

Strong/Force Cache

There’re two response headers for setting Strong Cache options for resources, which are corresponding to HTTP/1.0 and HTTP/1.1 perspectively.

If request hits Strong Cache, from memory or from disk will be showed in the size field on the Network Panel of DevTools.


  • HTTP Version: 1.0
  • Definition: Indicate the time when the cache expires, beyond which the resource expires.
  • Drawback: The expired time is set by server-side, but the real time can be set by client at will.


Expires header will become unavailable, when there is along with Cache-Control header.

  • HTTP Version: 1.1
  • The value is combination of multiple fields:

    • max-age, specifies the length of time during which the cache is valid, in seconds. It’s relative to the Request Time.
    • no-store, caching is prohibited(browser wouldn’t cache this resource), and data is retrieved from the server every time when a request is made. Notice, this value will disable HTTP caching including Strong Cache and Negotiation Cache.
    • no-cache, is mostly the same as max-age = 0 which is still cached, but go through the process of negotiation caching. The only difference is max-age=0 will leverage the cache on intermediate nodes(proxy, etc.) between browser and server, but no-cache will disable the intermediate cache request, so the returned resource is absolutely fresh when resource has been updated.
    • public, indicates the response can be set up by any object(client, proxy server, etc.), which means the response can be possible to be shared.
    • private, indicates the response can only be cached by a single user (possibly an operating system user or a browser user), and is not able to be shared or cached by a proxy server.

The process of working with Cache-Control

  1. if no-store exists, send request to server-side to retrieve resource.
  2. if no-cache exists, forward to negotiation cache.
  3. check is it expired by max-age.

For example:

  1. Cache-Control: no-cache
  2. Cache-Control: max-age=2000
  3. Cache-Control: max-age=20000, no-cache, forward to negotiation caching process even if cache is available.


  • HTTP Version: 1.0/1.1
  • no-cache, function as the same as Cache-Control: no-cache, which is compatible with HTTP 1.0 as an addition.

Negotiation Cache

Last-Modified header will be unavailable, when there exists Etag which is along with response.

Last-Modified and If-Modified-Since

  • HTTP Version: 1.0
  • The process:

    1. server-side responds resource along with Last-Modified, value of which is the last modified time of resource.
    2. while the next round resource request starts off, the request will be sent with If-Modified-Since header with the value of Last-Modified passed.
    3. once the If-Modified-Since value is not equal to the latest modified time of the specific resource, server-side will return the latest resource back and replace the old ones. On the contrary, return 304 http status code to ask the agent to read cache.
  • Drawback:

    1. Once the last modified time changes, a new resource will be sent from server-side, even if there is no any modification on content.
    2. Last-Modified can only be accurate to seconds.
    3. Some servers can not accurately get the last modified time of resources, so it’s impossible to judge whether resources are updated or not by it.

Etag and If-None-Match

  • HTTP Version: 1.1
  • The process is similar to Last-Modified and If-Modified-Since
  • Drawback:
    The value of Etag needs to be computed by the server, which is complex and consumes performance, depending on the specific situation.

How to calculate Etag ?


In koa2, the algorithm for Etag generation is separated into two categories:

  1. For static resource, the file size and mtime are taken into as factor to generate Etag;
  2. For string and buffer, the length and hash value matter the Etag.

The difference between F5 and Ctrl+F5

When F5 is pressed solely, Cache-Control: max-age=0 will be attached into the request header. Chances that the returning resource will be cached in the intermediate nodes. In contrast, pressing F5 along with Ctrl, Cache-Control: no-cache and Pragma: no-cache are both added to request header.