Cache-Control: must-revalidate 要求缓存必须验证后才能使用,而非禁止缓存;它强制再验证机制,确保数据一致性,适用于仪表盘、订单页等高一致性场景,需配合 max-age 使用,并依赖 ETag 或 Last-Modified 实现验证。

Cache-Control: must-revalidate 不是让浏览器“不缓存”,而是要求:即使本地有缓存副本,也必须先向服务器发起验证(比如带 If-None-Match 或 If-Modified-Since),只有收到 304 Not Modified 才能复用缓存;若服务器返回 200 OK(新内容),就必须更新缓存并返回新响应。它强制“再验证”,而非“跳过缓存”。
为什么需要 must-revalidate?
适用于对数据一致性要求高的场景,比如用户仪表盘、订单状态页、权限配置接口等——你允许客户端缓存,但绝不接受“过期却未感知”的风险。相比 no-cache(每次都要验证),must-revalidate 更明确地约束了缓存行为:即使客户端因网络异常无法验证,也不得使用过期缓存(而 no-cache 在某些实现中可能降级为“勉强用旧缓存”)。
Nginx 中如何正确设置 must-revalidate
注意:must-revalidate 本身不决定是否缓存,它只约束缓存的使用条件。你需要配合 max-age 或 expires 明确缓存有效期:
- 在 location 块中添加:
add_header Cache-Control "public, max-age=300, must-revalidate"; - 确保后端响应已带 ETag 或 Last-Modified(Nginx 默认对静态文件自动加 ETag;动态接口需后端生成)
- 避免同时设置
no-store或no-cache,它们会覆盖或削弱 must-revalidate 的语义
实战验证步骤(用 curl 模拟)
1. 首次请求,观察响应头和 ETag:curl -I https://example.com/api/status
→ 返回 200 OK,含 Cache-Control: public, max-age=300, must-revalidate 和 ETag: "abc123"
2. 5分钟内再次请求,带上 ETag 验证:curl -I -H 'If-None-Match: "abc123"' https://example.com/api/status
→ 若资源未变,Nginx(或上游服务)返回 304 Not Modified,不传响应体
3. 手动修改后端资源(如改数据库状态),再发相同验证请求:
→ 返回 200 OK + 新 ETag + 新响应体,客户端自动更新本地缓存
常见误区与调试提示
-
must-revalidate对private缓存(如浏览器)生效,但对public代理缓存(如 CDN)是否遵守,取决于其配置;CDN 通常支持,但需确认开启“源站校验”功能 - 如果始终收不到 304,检查 Nginx 是否透传了
If-None-Match/If-Modified-Since到后端(默认透传,除非显式用proxy_pass_request_headers off) - 浏览器开发者工具 Network 标签页中,查看“Size”列显示
from disk cache或from memory cache是正常现象;关键看状态码是否为 304


















