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-Since
和 If-None-Match
字段,询问服务器资源是否更新,其中:
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
缓存的last-modified时间,If-None-Match: "33a64df551425fcc55e4d42a1"
缓存的etag
这个时候,服务器会根据请求头中的 If-Modified-Since
和 If-None-Match
字段,来判断资源是否更新。
如果缓存已失效,资源已更新,那就把这个请求当作一个普通请求,执行代码逻辑,返回200,并返回资源,同样会返回新的缓存指令让浏览器缓存。
如果缓存未失效,资源未更新,那就返回304 Not Modified
以及新的缓存指令,浏览器直接使用缓存。
协商缓存最大好处是,浏览器可以缓存资源,减少请求,提高性能。
补充
Cache-Control
:除了max-age
,还有no-cache
、no-store
、public
、private
no-cache
缓存,但每次都要协商no-store
完全不使用缓存,每次都请求服务器
Expires
: 过期时间,HTTP1.0 的缓存指令,已废弃,不推荐使用, HTTP1.1 都是通过Cache-Control: max-age
来设置缓存时间Vary
: 缓存协商的依据,当服务器返回的响应头中包含Vary: *
时,表示缓存协商的依据是所有请求头字段,而不是请求头中的Cache-Control
和If-Modified-Since
字段。- 版本号和hash
- 早期,通常会手动在文件名上加个版本号,如
app.js?v=1.0.0
,当资源有变动时,手动更新版本号,cache miss,客户端也就会请求新的资源。 - 现在的构建工具都会在文件名中间添加hash,如
app.zvjio152.js
,这样可以让客户端大胆缓存资源,当资源有变动时,也会有新的hash,自动请求新的资源。
- 早期,通常会手动在文件名上加个版本号,如
自定义自维护的缓存实现
- Custom Cache: 自己在内存中维护缓存,简单点就是一个Map, 把请求结果或一些重要数据缓存起来,这样做就是Session级的数据缓存,当页面刷新时,缓存会丢失。
- LocalStorage / SessionStorage: 自己维护缓存,但只能存储字符串,容量有限,一般用于存储一些简单的且需要持久化的数据。
- IndexedDB:浏览器自带的本地数据库,可以存储结构化数据,支持事务,支持索引,支持查询,支持离线访问,支持同步,但我还没咋用过…
思考
- 什么是浏览器缓存?
- 什么是协商缓存,有何意义?