html不能被cdn强缓存,必须用no-cache+etag协商缓存以确保实时更新;cdn应专注缓存带contenthash的静态资源(如js/css/字体),配置immutable实现高效长期缓存。

HTML 缓存机制和 CDN 不是“一起缓存”,而是必须错开角色:HTML 不能靠 CDN 长期缓存,否则用户永远看不到新版本;CDN 的真正价值,在于加速那些带哈希的静态资源(main.abc123.js、style.def456.css),而不是 index.html。
为什么 HTML 绝对不能被 CDN 强缓存
CDN 缓存 HTML 的典型后果是:你发版后改了按钮文案、加了新功能,但用户刷新页面看到的还是旧 HTML——因为 CDN 返回了它自己缓存的副本,压根没去源站验证。
-
Cache-Control: public, max-age=3600这类配置如果落在index.html上,等于主动放弃更新控制权 - 哪怕你源站返回了
no-cache,CDN 后台若开启“自动缓存 HTML”(Cloudflare/阿里云默认常开),就会覆盖掉这个头 - 更隐蔽的问题:CDN 缓存 key 默认包含
Accept-Encoding,gzip 和 br 压缩版本被当成两个资源,可能一个更新了另一个没更新,导致 JS 解析失败
HTML 应该用 no-cache + ETag 协商缓存
这不是“不缓存”,而是让浏览器每次请求都带 If-None-Match,服务端比对 ETag 后决定返回 304 Not Modified 还是新内容。这样既省带宽,又保证实时性。
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- ETag 必须基于文件内容生成(如
md5(html_content)),不能只用Last-Modified时间戳——HTML 可能只改了内联脚本,时间变了但内容没变 -
<meta http-equiv="Cache-Control" content="no-cache">完全无效,现代浏览器和 CDN 都忽略它 - Nginx 示例:
location = /index.html { add_header Cache-Control "no-cache, must-revalidate"; etag on; }
CDN 缓存规则必须显式排除 HTML 或透传响应头
别依赖“CDN 会读你的 Cache-Control”,很多 CDN 默认不透传,尤其对 HTML 路径。
- 在 CDN 控制台里,找到 HTML 相关路径(比如
^/index\.html$或/*.html),手动设置为“缓存时间为 0”或“遵循源站响应头” - 验证是否生效:用
curl -I https://yoursite.com/index.html看返回头里有没有Cache-Control和ETag;再看 DevTools Network 面板中该请求是否出现304 - 如果用了多个子域名(
www.example.com/app.example.com),确认 CDN 缓存 key 是否包含Host字段,否则可能跨域名共享错误 HTML 缓存
静态资源必须带 contenthash + immutable
这才是 CDN 应该发力的地方。JS/CSS/字体这些文件一旦带哈希,内容不变 URL 就不变,CDN 可以放心缓存一年。
- Webpack 配置:
output.filename: "[name].[contenthash:8].js";Vite 默认启用,但要确认build.rollupOptions.output.entryFileNames有 hash - Nginx 配置示例:
location ~* \.(js|css|woff2|png)$ { expires 1y; add_header Cache-Control "public, immutable"; } -
immutable很关键:它告诉浏览器“这个 URL 永远不会变”,后续访问跳过协商流程,省一次网络往返;漏配会导致即使 URL 有 hash,浏览器仍可能复用旧缓存
最常被忽略的一点是:CDN 缓存策略和源站响应头不一致时,源站头大概率失效。调试永远从 curl -I 和 DevTools Network 面板的真实响应头开始,而不是看 CDN 控制台里写的“已启用缓存”。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










