目录
- 强缓存VS协商缓存
- **一、强缓存(本地缓存)**
- 1. **定义**
- 2. **核心 HTTP 头**
- 3. **缓存生效流程**
- 4. **应用场景**
- **二、协商缓存(条件请求)**
- 1. **定义**
- 2. **核心 HTTP 头**
- 3. **缓存生效流程**
- 4. **应用场景**
- **三、强缓存 vs 协商缓存**
- **四、实际使用建议**
- 1. **强缓存 + 文件名哈希(最佳实践)**
- 2. **协商缓存用于 HTML 文件**
- 3. **禁用缓存**
- **五、面试回答示例**
强缓存VS协商缓存
一、强缓存(本地缓存)
1. 定义
强缓存是指浏览器直接从本地缓存中读取资源,不向服务器发送请求。通过 HTTP 头中的 Expires
或 Cache-Control
字段控制。
2. 核心 HTTP 头
-
Expires
(HTTP/1.0):
指定资源的过期时间(绝对时间),例如:Expires: Wed, 21 Oct 2025 07:28:00 GMT
缺点:依赖客户端时间,时间误差可能导致缓存失效。
-
Cache-Control
(HTTP/1.1,优先级高于Expires
):
通过指令控制缓存行为,常用指令:Cache-Control: max-age=31536000 // 资源有效期(秒),例如 1 年 Cache-Control: public // 允许代理服务器缓存 Cache-Control: no-cache // 禁用强缓存,需协商缓存 Cache-Control: no-store // 完全禁用缓存
3. 缓存生效流程
graph TD浏览器请求资源 --> 检查缓存是否过期缓存未过期 --> 直接读取本地缓存(状态码 200 from cache)缓存过期 --> 向服务器发送请求
4. 应用场景
- 静态资源:如 CSS、JS、图片(文件名带哈希,例如
app.a1b2c3.js
)。 - 长期不变的资源:如公司 Logo、字体文件。
二、协商缓存(条件请求)
1. 定义
当强缓存失效时,浏览器向服务器发送请求,携带缓存标识,由服务器判断资源是否更新:
- 若未更新 → 返回 304(Not Modified),浏览器读取本地缓存。
- 若已更新 → 返回 200 和新资源。
2. 核心 HTTP 头
-
基于修改时间(精度低):
Last-Modified
(响应头):服务器返回资源的最后修改时间。If-Modified-Since
(请求头):浏览器将Last-Modified
的值带回给服务器。
-
基于内容标识(精度高,推荐):
ETag
(响应头):服务器返回资源的唯一标识(如哈希值)。If-None-Match
(请求头):浏览器将ETag
的值带回给服务器。
3. 缓存生效流程
graph TD强缓存过期 --> 浏览器携带 If-None-Match/If-Modified-Since 请求服务器服务器对比标识 --> 资源未更新 --> 返回 304 --> 浏览器读取本地缓存服务器对比标识 --> 资源已更新 --> 返回 200 和新资源
4. 应用场景
- 频繁更新的资源:如用户个人信息页面、动态生成的 JSON 数据。
- 需要实时性的资源:如新闻详情页、商品价格。
三、强缓存 vs 协商缓存
特性 | 强缓存 | 协商缓存 |
---|---|---|
是否发送请求 | 否(直接读缓存) | 是(携带标识验证) |
响应状态码 | 200 (from cache) | 304 (Not Modified) |
控制字段 | Expires /Cache-Control | Last-Modified /ETag |
优先级 | 先检查强缓存,失效再协商 | 强缓存失效后触发 |
四、实际使用建议
1. 强缓存 + 文件名哈希(最佳实践)
- 为静态资源(JS/CSS/图片)添加哈希指纹(如 Webpack 的
[contenthash]
):<script src="app.a1b2c3.js"></script>
- 配置
Cache-Control: max-age=31536000
(1 年),资源内容变化后哈希值改变,自动触发重新下载。
2. 协商缓存用于 HTML 文件
- HTML 文件不添加哈希,设置
Cache-Control: no-cache
,确保用户每次访问时通过协商缓存验证更新。
3. 禁用缓存
- 敏感数据(如用户隐私)设置
Cache-Control: no-store
。
五、面试回答示例
面试官:什么是强缓存和协商缓存?
回答:
强缓存和协商缓存是浏览器控制资源缓存的两种机制。
强缓存通过Cache-Control
或Expires
头实现,浏览器直接读取本地缓存,无需请求服务器,适合静态资源(如 JS、CSS)。
协商缓存在强缓存失效后触发,浏览器携带ETag
或Last-Modified
标识向服务器验证资源是否更新,若未更新返回 304,适合动态资源(如用户数据)。
实际项目中,我们会为静态资源添加哈希指纹并设置长期强缓存,HTML 文件使用协商缓存,确保用户及时获取最新内容。
面试官追问:如何设置强缓存?
回答:
在 Nginx 中配置静态资源的
Cache-Control
:location /static {expires 1y;add_header Cache-Control "public, max-age=31536000"; }
同时在前端构建时,为文件名添加哈希(如
app.[contenthash].js
),确保内容变化后 URL 改变,触发重新加载。