个人博客:haichenyi.com。感谢关注
一. 目录
- 一–目录
- 二–协议头和请求头
- 三–缓存策略
- 四–总结
二. 协议头和请求头
说浏览器的缓存策略之前,先说一下HTTP的协议头和请求头。
协议头:协议头包含请求头和响应头- 通用头:适用于请求和响应的通用元数据。如:Connection: keep-alive // 控制连接是否保持Cache-Control: max-age=3600 // 缓存策略Date: Wed, 21 Oct 2023 07:28:00 GMT // 消息生成时间- 请求头:客户端发送消息的附加消息。如Host: example.com // 目标服务器域名(HTTP/1.1必须)User-Agent: Mozilla/5.0 // 客户端标识Accept: text/html,application/json // 客户端可接受的响应类型Authorization: Bearer xyz123 // 身份验证凭据- 响应头:服务器返回响应时附加的信息。如Server: nginx/1.18.0 // 服务器标识Content-Type: text/html; charset=UTF-8 // 响应体的媒体类型Set-Cookie: sessionId=abc; Path=/ // 设置Cookie- 实体头:描述消息体(Body)的元数据。如Content-Length: 1024 // 消息体长度(字节)Content-Encoding: gzip // 消息体压缩方式
请求头
常见的请求头如下
请求头 | 示例值 | 用途 |
---|---|---|
Host | haichenyi.com | 指定目标服务器域名(HTTP/1.1强制要求) |
User-Agent | Mozilla/5.0 (Windows NT 10.0…) | 客户端标识(浏览器等等) |
Accept | text/html, application/json | 客户端接收的响应格式 |
Cookie | sessionId=abc; username=john | 发送给服务器之前设置的cookie |
Content-Type | application/json | 请求的媒体类型 |
Referer | http://www.haichenyi.com | 请求的来源页面 |
关键区别
- 协议头(HTTP Headers):泛指HTTP消息中的所有头部字段(包括请求头和响应头)。
- 请求头(Request Headers):特指客户端发送的HTTP请求中的头部字段。
三. 缓存策略
1.概念
浏览器的缓存策略是通过HTTP 协议头 和 本地存储机制 共同实现的。目的是减少重复请求,提升页面加载速度,降低服务器压力,提升用户体验。
2.缓存类型与流程
缓存类型:强制缓存 和 协商缓存
客户端请求资源——>检查强制缓存(Cache-Control/Expires)
↳ 如果强制缓存未过期——>直接读取缓存(状态码:200,从硬盘(dist),内存(memory) 缓存返回)
↳ 如果强制缓存已过期——>进入协商缓存(携带If-Modified-Since` 或 `If-None-Match)↳ 服务器验证资源是否修改(304 Not Modified —> 更新缓存时间,读取缓存)↳ 资源已修改——>返回新资源(状态码:200,更新缓存)
3.强制缓存(强缓存)
什么是强缓存? 当浏览器发起请求的时候,根据是否缓存的标记把数据缓存到本地。下次发起同一个请求的时候,会先判断缓存是否过期,如果没过期,就直接用本地的缓存数据返回。当次请求不会发到服务器去。
通过以下 HTTP 头控制:
(1)Cache-Control:值如下
- max-age=3600:资源有效期(秒),优先级高于Expires
Cache-Control: max-age=3600 // 1小时内使用缓存,时间可修改
- no-cache:禁用强制缓存,每次需向服务器验证(走协商缓存)
- no-store:完全禁用缓存(不存储任何缓存)
- public:允许代理服务器缓存资源
- private:仅允许浏览器缓存,禁止代理服务器缓存
(2)Expires
指定资源的过期时间(HTTP/1.0 的字段,已被 Cache-Control 替代):
Expires: Wed, 21 Oct 2023 07:28:00 GMT // 过期时间
4.协商缓存(对比缓存)
什么是协商缓存? 当强缓存失效时,浏览器携带认证信息向服务器发起请求,由服务器决定是否使用缓存。
通过以下 HTTP 头控制:
(1)Last-Modified与If-Modified-Since
- 服务器返回 Last-Modified 表示资源最后修改时间
Last-Modified: Wed, 21 Oct 2023 00:00:00 GMT
- 浏览器下次请求携带If-Modified-Since
If-Modified-Since: Wed, 21 Oct 2023 00:00:00 GMT
- 服务器对比时间
- 未修改—>返回304 Not Modified(浏览器读取缓存)
- 已修改—>返回200 OK和新资源
(2)ETag与If-None-Match
- 服务器返回ETag作为资源的唯一标识(哈希值):
ETag: "5d8c72a5-26c3" // 资源指纹
- 浏览器下次请求携带If-None-Match
If-None-Match: "5d8c72a5-26c3"
- 服务器对比ETag:
- 一致:返回 304
- 不一致:返回200和新资源
这里可能会存在一定的误解。当浏览器发起请求,发现强缓存失效,走协商缓存逻辑时,会携带If-Modified-Since到服务器,而对应的Last-Modified是第一次请求数据返回的时候一起返回的。If-None-Match的逻辑同理。举个栗子:
//(1) 首次请求
GET /data.txt HTTP/1.1
Host: example.comHTTP/1.1 200 OK
Last-Modified: Wed, 21 Oct 2023 00:00:00 GMT
Content-Length: 1024(资源内容)//(2) 后续请求(强缓存失效后)
GET /data.txt HTTP/1.1
Host: example.com
If-Modified-Since: Wed, 21 Oct 2023 00:00:00 GMT # 自动携带上次的 Last-ModifiedHTTP/1.1 304 Not Modified # 服务器确认资源未修改整个过程仅需一次请求,服务器直接返回 304 或 200。
(3)对比两种策略
策略 | 优点 | 缺点 |
---|---|---|
Last-Modified | 简单,兼容性好 | 精度到秒,文件内容未变但时间修改会失效 |
ETag | 精准(基于内容哈希) | 计算哈希消耗服务器资源 |
5.缓存存储位置
浏览器的缓存分为2种存储位置:
- 内存缓存(Memory Cache)
- 快速读取,tab关闭后失效
- 适用于高频小文件(如:css,js等)
- 磁盘缓存(Disk Cache)
- 持久化存储,容量大,读取较慢
- 适用于大文件(如图片,字体等等)
- Service Worker Cache
- 通用的Service Worker拦截请求,完全控制缓存逻辑(如:离线缓存)
6.实际应用策略
(1)静态资源(JS./CSS/图片)
- 设置长期缓存(如:Cache-Control: max-age=31536000)
- 通过文件哈希(如 main.abc123.js)或版本号更新URL,确保内容变化后URL变化,触发重新下载
(2)HTML页面 - 禁用强缓存(Cache-Control: no-cache),通过协商缓存验证
- 避免用户看到旧页面内容
(3)动态接口 - 根据业务需求选择
- 高频敏感数据—>短期缓存(max-age=60)
- 敏感数据—>no-store禁用缓存
7. 用户行为对缓存的影响
- 正常刷新(F5): 跳过强缓存,检查协商缓存
- 强制刷新(Ctrl+F5): 完全跳过缓存逻辑,请求头携带 Cache-Control: no-cache
- 地址栏回车: 优先使用强制缓存
8. 常见问题与解决
问题1:资源更新后用户未生效
- 解决: 修改文件名哈希或版本号(如 style.v2.css)。
- 调试: 通过 Chrome DevTools → Network → Disable cache 禁用缓存调试。
问题2:缓存策略配置错误
- 验证: 检查 HTTP 响应头(Cache-Control、ETag 等)。
- 工具: 使用 curl -I 查看响应头。
四. 总结
浏览器缓存策略的核心是通过 HTTP 头 控制资源缓存行为:
- 强制缓存(Cache-Control) → 快速响应,减少请求。
- 协商缓存(ETag/Last-Modified) → 精准验证资源更新。
合理配置缓存策略可显著提升 Web 应用性能,但需注意避免因缓存导致内容更新延迟问题。