强缓存优先于协商缓存,只要cache-control或expires有效,浏览器不发请求;no-cache禁止无验证使用缓存但允许存储,no-store才彻底禁用缓存;etag优于last-modified,html通常禁用强缓存以确保及时更新。

强缓存优先于协商缓存,只要 Cache-Control 或 Expires 有效,浏览器根本不会发请求——这是所有缓存逻辑的起点,不是“可选策略”,而是 HTTP 协议强制执行的流程。
为什么 Cache-Control: no-cache 不等于不缓存
这个词是面试里最常被误解的点。no-cache 的字面意思极具误导性:它不禁止缓存,而是禁止“无验证地使用缓存”。浏览器仍会把响应体存下来,但每次用之前必须带上 If-None-Match 或 If-Modified-Since 去和服务端确认。
-
no-store才是真·禁用缓存:内存、磁盘、CDN 全部跳过,连协商都不走 -
max-age=0和no-cache效果类似,但语义更清晰:缓存立即过期,强制进入协商阶段 - 如果响应头同时出现
Pragma: no-cache(HTTP/1.0 遗留字段),它优先级高于Cache-Control,会直接覆盖后者行为
ETag 和 Last-Modified 怎么选
ETag 是协商缓存的事实标准,Last-Modified 仅作兜底。原因很实际:
-
Last-Modified只能精确到秒,1 秒内多次变更文件内容,服务器返回的修改时间可能不变,导致缓存误命中 -
ETag是服务端生成的内容指纹(比如基于文件 hash),内容一变,ETag必变,可靠性高得多 - 但注意:如果部署在多台服务器上,且没统一 ETag 生成逻辑(比如用 inode 或本地文件 mtime),不同机器返回的
ETag可能不一致,反而破坏协商结果
HTML 文件为什么通常禁用强缓存
因为 HTML 是入口文件,哪怕只改了一行 JS 路径,若它被强缓存了 1 小时,用户就卡在旧版本里——JS/CSS 的哈希名再稳也没用。
- 典型配置:
Cache-Control: no-cache+ETag开启,让每次 HTML 请求都走协商,确保用户拿到最新结构 - 千万别写
max-age=31536000给 HTML,这不是优化,是埋雷 - 某些构建工具(如 Vite)默认对
index.html关闭强缓存,就是基于这个原则;自己配 Nginx 或 Node 服务时得手动检查
真正容易被忽略的是缓存链路的完整性:前端写了 Cache-Control: public, max-age=3600,但 CDN 没透传这个头,或者反向代理(如 Nginx)自己加了 Cache-Control: no-cache 覆盖掉,结果强缓存形同虚设。调问题时得一层层看响应头,而不是只信代码里写的那一行。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











