强缓存是否生效只取决于响应头中Cache-Control指令是否存在且未过期,与HTML是否为入口文件或内容是否变化无关;命中时浏览器不发任何请求,DevTools显示200(from memory/disk cache)。

强缓存不发请求,只看响应头里的 Cache-Control
浏览器对 HTML 文件是否走强缓存,根本不管它是不是“页面入口”,也不看文件内容有没有变——只严格检查服务器返回的响应头中是否存在有效的 Cache-Control 指令,且未过期。一旦命中,连 TCP 连接都不会建立,DevTools Network 面板里显示 200 (from memory cache) 或 200 (from disk cache),状态码是 200,但没有真实 HTTP 交互。
常见误区是以为 HTML 不能强缓存,或者必须配 no-cache 才安全。其实只要服务端返回了 Cache-Control: public, max-age=300,浏览器就会在 5 分钟内完全跳过请求,哪怕你点的是书签、地址栏回车、甚至 JS 跳转过去,都一样生效。
-
max-age是相对时间(秒),从响应被接收那一刻开始倒计时,不受客户端时间偏差影响 -
Expires在现代浏览器中基本被忽略,即使写了也压不过Cache-Control -
public和private对 HTML 影响不大,除非你用 CDN 或反向代理,否则默认行为已足够
no-cache 不等于“不缓存”,而是强制走协商流程
很多人把 no-cache 当作“禁止缓存 HTML”,结果发现页面还是没更新——因为 no-cache 其实允许浏览器存下 HTML,只是每次访问都必须带上 If-None-Match 或 If-Modified-Since 去和服务端确认。如果服务端返回 304 Not Modified,浏览器就继续用磁盘/内存里那个旧 HTML。
这意味着:HTML 文件本身还在缓存里,只是没被“直接复用”。如果你的服务端没正确返回 ETag 或 Last-Modified,或者构建流程导致这些值长期不变,no-cache 就会变成“永远 304”,用户卡在旧版本里出不来。
将 Markdown 文章转换为微信公众号兼容的纯 HTML 格式。当用户要求"转成微信格式"、"生成公众号文章 HTML"、"排版到微信草稿箱"、"微信粘贴格式"时触发。输出带内联样式的纯 HTML,微信编辑器可直接渲染,无需额外适配。支持标题、段落、列表、粗体、行内代码、表格、引用块、代码块、配图的完整转换。
立即学习“前端免费学习笔记(深入)”;
- 用
no-cache前,确保 Nginx / Apache / Node.js 服务端实际生成并返回了可靠的ETag - 静态托管平台(如 Vercel、Netlify)通常默认开启 ETag,但自建 Nginx 需显式配置
etag on; - 若构建产物无哈希、HTML 每次都重写,
Last-Modified可能每秒都变,反而让协商缓存失效
HTML 强缓存最容易踩的三个坑
HTML 是整个页面的入口,它的缓存行为直接影响所有子资源加载逻辑。强缓存配错,不是慢一点,而是整个更新链路断掉。
- 把
Cache-Control: max-age=31536000直接套在未哈希的index.html上——用户首次加载后,一年内都看不到新版本,连强制刷新(Ctrl+F5)都不行(因为强缓存不触发请求) - 误信
<meta http-equiv="Cache-Control" content="no-cache">能控制缓存——它在 Chrome/Firefox/Edge 中完全无效,只对极少数直接输入 URL 的场景有微弱影响 - 开发环境用
webpack-dev-server或vite,默认禁用强缓存(返回Cache-Control: no-cache),但上线后忘了配服务端头,导致生产环境意外启用强缓存
为什么推荐 HTML 用 no-cache 而不是 max-age=0
两者在 DevTools 里看起来都是“每次发请求”,但底层机制不同:max-age=0 属于强缓存过期,浏览器仍保留 HTML 在磁盘,只是降级走协商;而 no-cache 是明确指令“不许跳过验证”,语义更直白,中间代理(比如企业防火墙、CDN)也更容易按预期处理。
更关键的是:某些老旧代理会把 max-age=0 解析成“不缓存”,直接丢掉响应体;而 no-cache 是标准指令,兼容性更稳。如果你的部署链路里存在未知代理层,优先选 no-cache。
-
max-age=0:强缓存策略存在,只是有效期为零,仍可能被代理缓存或误解 -
no-cache:强缓存被禁用,强制进入协商阶段,语义清晰,行为可预测 - 真正需要“完全不缓存”的场景(如登录页、支付页),才用
no-store,但它会让 HTML 每次都重新下载,慎用


















