高级前端
http
【Q079】简述 http 的缓存机制

简述 http 的缓存机制

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

Author 回答者: jianxing-xu (opens in a new tab)

强缓存 协商缓存

Author 回答者: shfshanyue (opens in a new tab)

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 in a new tab)

    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

Author 回答者: Harry3014 (opens in a new tab)

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

假设第一次请求资源的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 (opens in a new tab)

Author 回答者: hututuQWQ (opens in a new tab)

补充一张图和一个链接, 162db635ed5f6d26~tplv-t2oaga2asx-jj-mark_3024_0_0_0_q75

https://juejin.cn/post/6844903593275817998 (opens in a new tab)