HTTP Protocol #
Http cache #
Recommended cache header #
Cache-Control:max-age=31622400
For specifying different proxy cache #
Cache-Control:s-maxage=31622400
To prevent storing of responses #
Cache-Control:no-cache, private
- No-cache: still stores the response, it just validateσ each time using etag/last-modified
- No-store: doesn’t’ store the response, but it does not delete the existing cache responses if they are present. Also breaks the back/forward cache
To specify private cache (only cache on the browser and not on proxies) #
Cache-Control: private
Vary response header can be used to create different caches based on a header #
Vary: Accept-Language
Validation - How browser finds if stale responses need to be updated #
Validation is done by using a conditional request that includes an If-Modified-Since or If-None-Match request header.
- Using If-Modified-Since:
- The server responds with 304 and no content if the page hasn’t been changed
- Upon receiving that response, the client reverts the stored stale response back to being fresh and can reuse it during the remaining max-age time
- Issues with this method: The time format is complex and difficult to parse, and distributed servers have difficulty synchronizing file-update times.
- To solve these problems, the ETag response header was standardized as an alternative
Using If-None-Match Etag #
- The server returns the ETag header along the response
- On stale cache responses, the client sends the If-None-Match request header with the value of the cached ETag
- During cache revalidation, if both ETag and Last-Modified are present, ETag takes precedence
Last-Modified header #
if you are only considering caching, you may think that Last-Modified is unnecessary.
However, Last-Modified is not just useful for caching; instead, it is a standard HTTP header that is also used by:
- Content-management (CMS) systems to display the last-modified time
- By crawlers to adjust crawl frequency
- And for other various purposes
So considering the overall HTTP ecosystem, it is preferable to provide both ETag and Last-Modified.
Browser Reload #
The following request-headers are sent by the browser upon reload
Cache-Control: max-age=0
If-None-Match: "deadbeef"
If-Modified-Since: Tue, 22 Feb 2022 20:20:20 GMT
- Chrome only validates the main page and not the included resources
- The requests from Chrome, Edge, and Firefox look very much like the above; the requests from Safari will look a bit different.
- To force a page not to be re-validated on reload, use the immutable directive
Cache-Control: max-age=31536000, immutable
Browser Force Reload #
The following request-headers are sent by the browser upon force-reload
Pragma: no-cache
Cache-Control: no-cache
Cache types #
Heuristic caching #
Caches even if the Cache-Control is given
For example, take the following response. This response was last updated 1 year ago.
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 1024
Date: Tue, 22 Feb 2022 22:22:22 GMT
Last-Modified: Tue, 22 Feb 2021 22:22:22 GMT
It is heuristically known that content which has not been updated for a full year will not be updated for some time after that.
Therefore, the client stores this response (despite the lack of max-age) and reuses it for a while. How long to reuse is up to the implementation, but the specification recommends about 10% (in this case 0.1 year) of the time after storing.
Heuristic caching is a workaround that came before Cache-Control support became widely adopted, and basically all responses should explicitly specify a Cache-Control header.
References #
Online HTTP fetch - REST & SOAP requests #
reqbin.com Online REST & SOAP API Testing Tool
Online HTTP request /header viewer #
Example:
GET https://postman-echo.com/get?foo1=bar1&foo2=bar2