HTTP 缓存机制速查
强缓存与协商缓存的分工、Cache-Control 每个指令到底说什么、ETag 与 Last-Modified 怎么配合,以及 no-cache 和 no-store 的关键差别。
缓存的作用是让浏览器或少走一次网络,或多省一次传输。展开说有两层:一层是浏览器直接拿本地副本、连请求都不发(强缓存);另一层是发个请求去问服务器「我这份还能用吗」(协商缓存)。
理解这两层之后,「为什么改了代码用户还是看到旧页面」和「为什么每次刷新都重新下载」这两个看似矛盾的问题就都能解释了——它们是同一套机制在不同配置下的结果。
1两步判定:强缓存在前,协商缓存在后
浏览器要一个资源时,按固定顺序判断,只有前一步不通过才会走到下一步。
| 阶段 | 触发条件 | 是否发出请求 | 服务器返回 |
|---|---|---|---|
| 强缓存命中 | 本地副本仍在 max-age 有效期内 | 不发请求 | 无(直接读本地) |
| 强缓存过期 | 超出有效期或设为必须校验 | 发出请求(带校验头) | 由服务器决定 |
| 协商缓存命中 | 校验信息表明内容未变 | 发了请求 | 304 Not Modified,不含正文 |
| 协商缓存未命中 | 内容已变更 | 发了请求 | 200 OK 加新的完整正文 |
| 无任何缓存头 | 响应里没有缓存指令 | 每次发请求 | 由服务器按启发式规则处理 |
`304` 虽然也走了一次网络往返,但省掉了正文传输。对体积大的文件(图片、字体)收益明显;对很小的接口响应,节省有限,反而多一次往返。
2Cache-Control 指令对照
这是控制缓存行为的核心头部,可以组合多个指令。理解每个指令「否定的是哪一步」,比死记名字更管用。
| 指令 | 含义 | 实际效果 |
|---|---|---|
max-age=3600 | 响应在 3600 秒内可直接复用 | 强缓存的有效期,从响应生成时刻算起 |
s-maxage=600 | 同上,但只约束共享缓存(CDN、代理) | 可让 CDN 缓存更短,浏览器缓存更长 |
no-cache | 可以存,但每次使用前必须向服务器校验 | **跳过强缓存,走协商缓存**(并未禁止缓存) |
no-store | 完全禁止存储任何副本 | 既不存也不用,最彻底的禁用,适合含敏感信息的响应 |
private | 只允许浏览器这类私有缓存保存 | 阻止 CDN 与代理缓存,常用于带用户身份的响应 |
public | 允许任何缓存保存 | 即使带 Authorization 头也可被 CDN 缓存 |
must-revalidate | 过期后必须先校验,不得使用陈旧副本 | 断网时不会拿过期内容凑合,而是报错 |
immutable | 在有效期内明确不会变化 | 用户刷新页面时也不再发校验请求,适合带指纹的资源 |
stale-while-revalidate=60 | 过期后 60 秒内可先用旧副本 | 后台同时异步更新,换来更快的首屏 |
`no-cache` 名字最有误导性:它并不表示「不缓存」,而是「使用前必须校验」。真正想禁止缓存要用 `no-store`。这两个词搞反是排查缓存问题时最浪费时间的一类误解。
3校验型头部:ETag 与 Last-Modified
协商缓存靠一组「请求头带校验值、响应头给出校验值」的头部工作。两者各有局限,同时提供时服务器可自行选择依据。
| 响应头(服务器给出) | 请求头(浏览器回传) | 依据 | 精度 |
|---|---|---|---|
ETag | If-None-Match | 内容指纹(如哈希) | 精确到内容,内容没变值就不变 |
Last-Modified | If-Modified-Since | 最后修改时间 | 精确到秒,秒内多次修改会漏判 |
ETag 弱校验 W/ 前缀 | If-None-Match | 语义等价即可 | 允许内容有细微差异仍算未变 |
| 两者同时存在 | 浏览器同时带上 | 服务器优先用 ETag | ETag 不一致则返回 200 加新内容 |
| CDN 场景 | Vary 头参与缓存键 | 按 Vary 指定的头区分副本 | 如 Vary: Accept-Encoding 区分压缩与未压缩版 |
多台服务器做负载均衡时,如果 `ETag` 由各自机器单独生成(例如带 inode 的实现),同一份资源在不同机器上会得到不同 `ETag`,导致协商缓存频繁失效。这类场景应改用基于内容哈希的 `ETag`,或干脆关掉 `ETag` 只留 `Last-Modified`。
4一套常见的缓存策略
「HTML 不缓存、静态资源长缓存」是最主流的组合。核心思路是让变化的入口始终新鲜,让不变的资源尽可能待在本地。
- HTML 入口
- 设
Cache-Control: no-cache(或很短max-age),每次校验。入口文件很小,校验成本低,保证了发版后用户能立刻拿到新版本 - 带指纹的静态资源
- 文件名里含内容哈希(如
app.9f3c2a.js),设max-age为一年并加immutable。内容变了文件名就变,天然规避缓存 - 不带指纹的资源
- 设较短
max-age并配合ETag校验,用时间换正确性 - 接口响应
- 按数据时效性决定:几乎不变的字典数据可缓存,实时数据用
no-store - CDN 策略
- 静态资源交给 CDN 长缓存,HTML 走回源校验,
s-maxage控制 CDN 侧的有效期 - 发版注意
- 只要入口 HTML 不放长缓存,用户下次访问就会拿到引用新指纹资源的页面,不需要额外清缓存操作
5四个高频误区
- 改了代码但用户看到旧版
- 通常是入口 HTML 被缓存了。检查 HTML 的响应头里是否有长
max-age,把它改成no-cache或很短的max-age - 每次访问都重新下载
- 响应里缺少缓存头,或设成了
no-store。确认静态资源是否配了max-age与ETag - 刷新和直接访问行为不同
- 浏览器刷新(F5)会自动给主文档带上
no-cache语义去校验,Ctrl+F5 则连子资源也强制跳过缓存。所以「刷新后正常」不代表普通用户也正常 - 关掉缓存就万事大吉
- 把全部资源设成
no-store会显著拖慢重复访问,且增加服务器与带宽压力。正确做法是分层:入口校验、资源长缓存
看完就能用的站内工具
全部工具总览 →生成 Cache-Control 响应头,支持 public 与 private、max-age、s-maxage、immutable、must-revalidate 等指令,附常用资源类型的缓存天数换算。
在线设计 CDN 缓存规则并生成 Nginx 与 Cloudflare 配置片段,按路径模式设置 TTL 与 immutable 策略并统计缓存分布
在线解析 HTTP 响应头,逐项检查 HSTS、CSP、X-Frame-Options 等八项安全头是否齐全,同时提示 Server、X-Powered-By 等信息泄露头与缓存策略配置,并给出安全评分,粘贴响应头即可出结果。
在线检测 URL 重定向链条的跳数、跨域跳转与循环死循环,输出最终落地 URL 与逐跳明细
关于「HTTP 缓存机制速查」的常见问题
no-cache 和 no-store 有什么区别?
这是缓存里最容易混淆的一对。no-cache 的意思是「可以存副本,但每次使用前必须先向服务器校验」,所以它跳过的只是强缓存,仍然可能返回 304 省下正文传输;no-store 则是「完全禁止保存任何副本」,浏览器不存、也不用,每次都要完整重新下载。想把一份含敏感信息的响应彻底排除在缓存之外,要用 no-store;想让页面每次都用最新版本但保留校验带来的带宽节省,用 no-cache 就够。
强缓存和协商缓存有什么区别?
强缓存命中时浏览器连请求都不发,直接用本地副本,速度最快,代价是在有效期内无法感知服务器上的更新。协商缓存则是浏览器发出请求并带上校验值(If-None-Match 或 If-Modified-Since),服务器比对后如果内容没变就返回 304,省掉正文传输但仍有一次网络往返。所以选择依据是「这个资源多久会变」:长期不变的用强缓存并配长有效期,可能随时变的用协商缓存保证及时性。实践中两者往往配合使用。
为什么修改了网页,用户看到的还是旧版本?
九成是入口 HTML 被强缓存了。资源文件通常带内容指纹(文件名里有哈希),改了就换名字不会冲突;但 HTML 的文件名固定,一旦被浏览器或 CDN 长时间缓存,用户就一直在用旧页面。解决方式是给 HTML 设置 no-cache 或很短的 max-age,让它每次都走校验;同时确保静态资源文件名带指纹。这样发版后用户下一次访问就能自动拿到新版本,不需要提示他们清缓存。
ETag 和 Last-Modified 该用哪个?
两者都用于协商缓存,最好同时提供,服务器可自行选择。Last-Modified 基于最后修改时间,实现简单,但精度只到秒,同一秒内的多次修改可能漏判,而且文件被重新生成内容没变时时间也会变,导致不必要的下载。ETag 基于内容生成的指纹,只要内容没变值就不变,判断更准确。需要注意的是在多台服务器做负载均衡时,如果 ETag 由各机器独立生成,同一资源可能得到不同值,反而频繁失效,这时应改用内容哈希生成 ETag 或只保留 Last-Modified。
继续查:相关内容
全部速查 →内容说明:本页速查数据由本站自行整理,事实性内容以对应官方规范与文档为准,未复制第三方速查表或百科的表述。数据最后核对日期:2026-10-05。若发现错误或已更新的标准,欢迎通过页脚反馈入口告知。
速查在线工具箱