极客时间返利平台,你可以在上边通过山月的链接购买课程,并添加我的微信 (shanyue94) 领取返现。

# 简述 http 的缓存机制

Issue

欢迎在 Gtihub Issue 中回答此问题: Issue 80 (opens new window)

Author

回答者: xuanyyyy (opens new window)

强缓存 协商缓存

Http 缓存分为以下两种,两者都是通过 HTTP 响应头控制缓存

  1. 强制缓存
  2. 协商缓存

# 强制缓存

再次请求时无需再向服务器发送请求

              client         server
GET /a.ab389z.js ------->
                      <------- 200 OK
(再也不会发请求)

与之相关的 Response Headers 有以下几个

  • Expires

    这个头部也是丧心病狂:使用绝对时间,且有固定的格式 https://tools.ietf.org/html/rfc822#section-5.1 (opens new window)

    Expires: Mon, 25 Oct 2021 20:11:12 GMT
    
  • Cache-Control,具有强大的缓存控制能力

    常用的有以下两个

    • no-cache,每次请求需要校验服务器资源的新鲜度
    • max-age=31536000,浏览器在一年内都不需要向服务器请求资源

# 协商缓存

再次请求时,需要向服务器校验新鲜度,如果资源是新鲜的,返回 304,从浏览器获取资源

           client         server
GET /a.js   ----------->
                   <----------- 200 OK
GET /a.js   ----------->
                   <----------- 304 Not Modified

与之相关的 Request/Response Headers 有以下几个

  • Last-Modified/If-Modified-Since
  • Etag/If-None-Match

今天在看这个问题的时候,发现一个关于强制缓存的意外情况。在刷新页面时,有的浏览器会重新验证缓存资源的新鲜度,有的不会。

假设第一次请求资源的 Response Heades 包含下列强制缓存信息

Date: Tue, 19 Jan 2021 08:37:05 GMT
Expires: Tue, 26 Jan 2021 08:37:05 GMT

在有效期内,按照强制缓存的概念解释,再次请求资源时,不会发送请求,直接返回 200。 但是在 firefox 中(使用版本:84.0.2),Request Headers 中包含If-Modified-Since头部,所以仍然会发送请求,返回 304。 在 chrome 中(使用版本:87.0.4280.141),不会发送请求,会直接使用缓存的资源,返回 200。

在 stackoverflow 找到了一些关于这个问题的回答https://stackoverflow.com/questions/45829055/why-doesnt-chrome-re-validate-in-memory-cache-when-doing-a-normal-reload/57281076#57281076

Last Updated: 6/26/2022, 10:48:10 AM