文章目录
- 前言
-
- [**1. 强缓存(强制缓存)**](#1. 强缓存(强制缓存))
- **强缓存生效流程**:
- [**2. 协商缓存(对比缓存)**](#2. 协商缓存(对比缓存))
- **协商缓存生效流程**:
- **对比总结**
- **实际应用建议**
- [**1. 缓存配置的三种主要实现方式**](#1. 缓存配置的三种主要实现方式)
前言
强缓存与协商缓存的实现机制
1. 强缓存(强制缓存)
特点:浏览器直接从本地缓存读取资源,不发送请求到服务器。
实现方式:通过 Cache-Control
和 Expires
响应头控制。
(1) Cache-Control
(HTTP/1.1 标准,优先级更高)
• 常见指令:
• max-age=<seconds>
:缓存有效期(如 max-age=3600
表示 1 小时内有效)。
• no-cache
:不使用强缓存,直接进入协商缓存(向服务器验证)。
• no-store
:完全禁用缓存,每次请求都重新获取资源。
• public
:允许代理服务器缓存(默认 private
仅浏览器缓存)。
• immutable
:资源永不变,浏览器直接使用缓存(适用于版本化文件名如 main.a1b2c3.js
)。
• 示例:
http
Cache-Control: public, max-age=3600
(2) Expires
(HTTP/1.0 遗留,优先级低于 Cache-Control
)
• 指定一个绝对过期时间(GMT 格式),若本地时间超过该时间则缓存失效。
• 示例:
http
Expires: Wed, 21 Oct 2025 07:28:00 GMT
强缓存生效流程:
- 浏览器请求资源时,检查
Cache-Control
/Expires
。 - 若未过期,直接从 内存缓存(Memory Cache) 或 磁盘缓存(Disk Cache) 加载,HTTP 状态码显示 200 (from cache)。
- 若已过期,进入协商缓存流程。
2. 协商缓存(对比缓存)
特点:浏览器向服务器验证缓存是否有效,可能返回 304(Not Modified) 继续使用缓存。
实现方式:通过 Last-Modified
/If-Modified-Since
和 ETag
/If-None-Match
两组头部控制。
(1) Last-Modified
+ If-Modified-Since
• 服务器返回 Last-Modified
:资源的最后修改时间(GMT 格式)。
• 浏览器下次请求:携带 If-Modified-Since
(值为上次的 Last-Modified
)。
• 服务器检查:
• 若资源未修改(时间未变),返回 304 Not Modified,浏览器使用缓存。
• 若已修改,返回 200 OK 和新资源。
• 示例:
http
# 首次请求(服务器响应)
Last-Modified: Wed, 21 Oct 2025 07:28:00 GMT
# 再次请求(浏览器携带)
If-Modified-Since: Wed, 21 Oct 2025 07:28:00 GMT
(2) ETag
+ If-None-Match
(更精准)
• 服务器返回 ETag
:资源的唯一标识符(如哈希值)。
• 浏览器下次请求:携带 If-None-Match
(值为上次的 ETag
)。
• 服务器检查:
• 若 ETag
匹配,返回 304 Not Modified。
• 若不匹配,返回 200 OK 和新资源。
• 示例:
http
# 首次请求(服务器响应)
ETag: "33a64df551425fcc55e4d42a148795d9"
# 再次请求(浏览器携带)
If-None-Match: "33a64df551425fcc55e4d42a148795d9"
协商缓存生效流程:
-
浏览器发现强缓存失效(或
no-cache
),携带If-Modified-Since
或If-None-Match
向服务器发起请求。 -
服务器验证资源是否变化:
• 未变化 → 返回 304,浏览器使用缓存。
• 已变化 → 返回 200 和新资源。
对比总结
缓存类型 | 实现方式 | 优先级 | 特点 |
---|---|---|---|
强缓存 | Cache-Control /Expires |
高 | 直接读缓存,不请求服务器。 |
协商缓存 | Last-Modified /ETag |
低 | 需向服务器验证,可能返回 304。 |
实际应用建议
-
静态资源(如 JS/CSS/图片):
• 使用强缓存 + 文件名哈希(如
main.a1b2c3.js
),设置Cache-Control: max-age=31536000, immutable
。 -
动态资源(如 API 数据):
• 使用
Cache-Control: no-cache
+ETag
,确保实时性。 -
避免缓存问题:
• 修改资源时更新文件名或 URL 参数(如
?v=2
)。
通过合理配置,可显著减少网络请求,提升页面加载速度! 🚀
1. 缓存配置的三种主要实现方式
(1) 后端代码控制(如Node.js/Java/Python)
适用场景:动态API、需要业务逻辑判断是否缓存。
示例(Node.js Express):
javascript
app.get('/data', (req, res) => {
// 强缓存:1小时有效
res.set('Cache-Control', 'public, max-age=3600');
// 协商缓存:ETag
const data = { id: 1, name: 'Example' };
const etag = require('crypto').createHash('md5').update(JSON.stringify(data)).digest('hex');
res.set('ETag', etag);
// 检查客户端If-None-Match
if (req.headers['if-none-match'] === etag) {
return res.status(304).end(); // 返回304,使用缓存
}
res.json(data);
});
(2) Web服务器配置(如Nginx/Apache)
适用场景:静态资源(HTML/CSS/JS/图片)的缓存。
Nginx示例:
nginx
server {
location /static/ {
# 强缓存:1年(适用于版本化文件名如main.a1b2c3.js)
add_header Cache-Control "public, max-age=31536000, immutable";
# 协商缓存:Last-Modified/ETag(默认启用,无需额外配置)
}
location /api/ {
# 动态接口禁用强缓存,只用协商缓存
add_header Cache-Control "no-cache";
# Nginx会自动处理ETag/Last-Modified(需确保后端未覆盖)
}
}
(3) CDN控制(如Cloudflare/AWS CloudFront)
适用场景:全球加速的静态资源缓存。
Cloudflare规则示例:
• 缓存规则:匹配URL路径(如/images/*
),设置缓存有效期(如1小时)。
• 边缘缓存TTL:覆盖源站的Cache-Control
头。
2. 缓存策略选择与优先级
(1) 缓存配置的优先级
-
CDN设置 > Nginx配置 > 后端代码
• 如果CDN设置了缓存规则,它会覆盖Nginx或后端的
Cache-Control
头。• 如果Nginx配置了
add_header
,它会覆盖后端代码的响应头。
(2) 如何决定使用哪种方式?
场景 | 推荐方式 | 理由 |
---|---|---|
静态资源(JS/CSS/图片) | Nginx/CDN | 高效、无需业务逻辑,直接通过文件名哈希(如main.a1b2c3.js )和强缓存优化。 |
动态API数据 | 后端代码 | 需要根据业务逻辑判断是否缓存(如用户隐私数据不可缓存)。 |
全局缓存策略 | CDN | 统一管理所有边缘节点的缓存行为,适合多地域部署。 |
(3) 强制禁用缓存的场景
• 需要实时数据的API(如股票价格):
http
Cache-Control: no-store
• 用户敏感信息(如个人资料):
http
Cache-Control: private, no-cache
3. 实战建议
(1) 静态资源优化
nginx
location /assets/ {
# 文件名带哈希(如main.a1b2c3.js),强缓存1年
add_header Cache-Control "public, max-age=31536000, immutable";
}
• 使用Webpack/Vite等工具生成哈希文件名,确保内容变化后URL改变。
(2) 动态API优化
javascript
// 后端代码(Express/Koa)
res.set({
'Cache-Control': 'no-cache', // 禁用强缓存,但允许协商缓存
'ETag': generateETag(data) // 基于内容生成ETag
});
(3) 调试缓存行为
• Chrome DevTools → Network → 查看请求头(Cache-Control
/ETag
)和响应状态(200
/304
)。
• cURL命令测试:
bash
curl -I http://example.com/resource
# 检查响应头中的Cache-Control/ETag
总结
• 谁控制缓存?
• 静态资源 → Nginx/CDN
• 动态API → 后端代码
• 全局策略 → CDN
• 如何选择?
• 强缓存:Cache-Control: max-age=3600
(Nginx/CDN优先)。
• 协商缓存:ETag
/Last-Modified
(后端或Nginx自动处理)。
• 调试工具:Chrome DevTools、cURL、Web服务器日志。
合理配置缓存可显著提升性能,减少服务器压力! 🚀