HTTP缓存-计网(7)

Date:

HTTP协议驱动的浏览器的默认行为之缓存

目录

浏览器缓存

将某次请求的响应结果缓存在客户端,在下次请求时,如果缓存有效,则直接使用缓存,否则重新请求。

涉及的问题:

  • 哪些应该缓存?
  • 缓存的时间?
  • 如果同样的接口,返回资源变了,那怎么更新客户端缓存?

响应头中的缓存指令(服务端设置)

和Cookie类似,浏览器在和服务器交互过程中,会有一些默认行为,缓存也一样。

  • Cache-Control: max-age=3600 缓存时间,单位为秒
  • ETag: "33a64df551425fcc55e4d42a1" 缓存标识
  • Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT 上次修改时间
  • Expires: Wed, 21 Oct 2025 07:28:00 GMT 过期时间

当响应头中包含这些指令时,浏览器会根据这些指令来缓存资源。刷新网页,在网络面板可以看到 memory cache 和 disk cache 的缓存。

浏览器缓存

请求头中的缓存指令(客户端设置)

客户端在发出请求时,会先检查缓存,如果缓存有效,则直接使用缓存,否则重新请求。

主要检查 缓存中是否有匹配的请求方法及URL,如果有,则检查缓存是否过期,如果过期,会带缓存请求;如果未过期,则直接使用缓存。

带缓存的请求(协商缓存)

在请求头中,会带上 If-Modified-SinceIf-None-Match 字段,询问服务器资源是否更新,其中:

  • If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT 缓存的last-modified时间,
  • If-None-Match: "33a64df551425fcc55e4d42a1" 缓存的etag

这个时候,服务器会根据请求头中的 If-Modified-SinceIf-None-Match 字段,来判断资源是否更新。

如果缓存已失效,资源已更新,那就把这个请求当作一个普通请求,执行代码逻辑,返回200,并返回资源,同样会返回新的缓存指令让浏览器缓存。

如果缓存未失效,资源未更新,那就返回304 Not Modified以及新的缓存指令,浏览器直接使用缓存。

协商缓存最大好处是,浏览器可以缓存资源,减少请求,提高性能。

协商缓存

补充

  • Cache-Control:除了max-age,还有no-cacheno-storepublicprivate
    • no-cache 缓存,但每次都要协商
    • no-store 完全不使用缓存,每次都请求服务器
  • Expires: 过期时间,HTTP1.0 的缓存指令,已废弃,不推荐使用, HTTP1.1 都是通过 Cache-Control: max-age 来设置缓存时间

  • Vary: 缓存协商的依据,当服务器返回的响应头中包含 Vary: * 时,表示缓存协商的依据是所有请求头字段,而不是请求头中的 Cache-ControlIf-Modified-Since 字段。

  • 版本号和hash
    • 早期,通常会手动在文件名上加个版本号,如app.js?v=1.0.0,当资源有变动时,手动更新版本号,cache miss,客户端也就会请求新的资源。
    • 现在的构建工具都会在文件名中间添加hash,如app.zvjio152.js,这样可以让客户端大胆缓存资源,当资源有变动时,也会有新的hash,自动请求新的资源。

自定义自维护的缓存实现

  • Custom Cache: 自己在内存中维护缓存,简单点就是一个Map, 把请求结果或一些重要数据缓存起来,这样做就是Session级的数据缓存,当页面刷新时,缓存会丢失。
  • LocalStorage / SessionStorage: 自己维护缓存,但只能存储字符串,容量有限,一般用于存储一些简单的且需要持久化的数据。
  • IndexedDB:浏览器自带的本地数据库,可以存储结构化数据,支持事务,支持索引,支持查询,支持离线访问,支持同步,但我还没咋用过…

思考

  • 什么是浏览器缓存?
  • 什么是协商缓存,有何意义?