HTTP 缓存排障:分清 no-cache、no-store 和 ETag
浏览器明明拿到了 304,为什么页面还是发起了请求?接口响应里写了 no-cache,是否代表完全不能缓存?遇到“缓存不生效”时,如果只盯着状态码,很容易把缓存新鲜度、重新验证和禁止存储混在一起。本文从排障角度梳理常见指令,并给出一套可复现的检查顺序。
1. 先把“缓存”拆成三个问题
一次响应是否被缓存,至少要分开看三个问题:缓存能不能存、存了以后多久算新鲜、变旧后是否需要向源站验证。Cache-Control 的不同指令分别回答这些问题。
max-age=60 表示响应在 60 秒内可以按新鲜响应复用。它描述的是新鲜度,并不等于浏览器 60 秒内绝对不会发请求;用户强制刷新、缓存策略和请求头都可能改变行为。
no-store 的含义更严格:缓存不得存储请求或响应的任何部分,也不能用这份响应满足后续请求。它适合包含一次性凭证或敏感结果的响应,但它不会替代传输加密、权限控制和日志脱敏。
no-cache 容易被误解。它不是“不允许存储”,而是每次复用前都必须转发请求进行验证,并在验证成功后才能继续使用已保存的响应。也就是说,响应可以留在缓存里,但不能未经验证直接拿来用。
2. 304 不是“没有缓存”
客户端带着 If-None-Match 或 If-Modified-Since 发起条件请求。源站判断资源没有变化时,可以返回 304 Not Modified,不重复传输正文。客户端随后使用本地保存的表示,因此网络面板里会看到一次请求,但响应体大小很小。
304 只适用于条件 GET 或 HEAD。它不能单独证明缓存一定命中,也不能证明业务数据已经更新;要确认复用的内容,应查看响应头里的 ETag、Last-Modified、Age、Cache-Control 和 Via 等字段,并确认浏览器的 Size 列是否标记为缓存读取。
如果服务端每次生成不同的 ETag,即使正文没有变化,条件请求也会得到 200;如果中间层删除了 ETag,客户端就无法按实体标签验证。排查时应分别抓取浏览器到网关、网关到源站的请求,确认条件头是否在链路中保留。
3. ETag 是版本标识,不是加密摘要
ETag 是资源表示的实体标签,可以是强标签,也可以带 W/ 前缀表示弱比较。应用不应把它当作安全签名,也不应把用户权限信息编码进标签。它的目标是帮助缓存判断“这份表示是否仍然是同一个版本”。
常见流程如下:
第一次响应:ETag: "v42"
后续请求:If-None-Match: "v42"
未变化:返回 304
已变化:返回 200 和新的 ETag
多节点部署时,所有节点需要对同一资源生成稳定且一致的标签,否则请求在不同节点间切换时会出现“有时 304、有时 200”。如果资源依赖用户身份或地区,还要检查 Vary 以及共享缓存的隔离规则,避免把一个用户的表示错误地提供给另一个用户。
4. 一套不依赖猜测的排障顺序
第一步,确认请求 URL、查询参数和请求方法完全一致。缓存键通常包含这些信息,参数顺序或版本号变化都可能导致新请求。
第二步,记录完整的缓存相关响应头:Cache-Control、Expires、ETag、Last-Modified、Vary、Age,以及代理添加的 Via 或 X-Cache。不要只截取状态码。
第三步,检查请求头是否带了 Cache-Control: no-cache、Pragma: no-cache 或 Cookie。客户端主动要求重新验证时,服务端返回 304 仍然是正常现象。
第四步,绕过浏览器直接请求网关和源站,比较两段响应的 ETag、Date 和 Cache-Control。若源站正确而网关错误,重点检查反向代理的缓存规则;若源站标签不稳定,再回到应用生成逻辑。
第五步,构造一个内容明确变化的测试版本,并记录从发布到命中新版本的时间。不要用“我刚改了文件但页面没变”作为唯一证据,因为中间可能存在服务端渲染缓存、CDN 缓存和浏览器缓存三层。
5. 安全和一致性边界
登录态、支付结果、个人资料等响应应谨慎设置 private 或 no-store,并检查共享缓存是否真的遵守规则。Cache-Control: no-store 不是隐私保护的完整方案,敏感数据仍可能出现在浏览器历史、应用日志、监控采样或错误报告中。
对静态脚本和样式,可以使用带内容哈希的文件名配合较长 max-age;发布新版本时生成新文件名,避免依赖缓存失效的精确时间。对必须快速更新的配置接口,可以短 max-age、no-cache 验证或显式版本号换取更强的一致性。
缓存策略是性能和一致性的取舍。先分清存储、新鲜度和验证,再结合请求头、响应头和链路中的每一层代理定位问题,通常比反复点击强制刷新更快找到根因。
写作说明:本文由 AI 辅助编写,示例为独立构造的通用技术说明。
- 点赞
- 收藏
- 关注作者
评论(0)