html不能强缓存,因其含动态内容(如登录态、ab测试、实时数据),设long-term cache-control会导致用户长期无法获取更新;应配no-cache或max-age=300+etag协商验证,静态资源则用contenthash+immutable长期缓存。

HTML本身不能被强缓存,强行缓存会导致用户看不到新版页面——这是最常踩的坑。
为什么不能给HTML设 long-term Cache-Control
浏览器对HTML文件的缓存策略必须和「内容可变性」匹配。HTML通常是动态入口:路由跳转、登录态、AB测试、实时数据都会改变它。一旦配置 Cache-Control: public, max-age=31536000,用户在缓存有效期内永远拿不到新版本,连强制刷新(F5)都无效——因为强缓存未过期时,浏览器压根不发请求。
- 强缓存生效期间,
ETag和Last-Modified完全不参与校验 - CDN 或中间代理可能比你更早缓存了旧 HTML,且你无法主动清除
- 即使你改了 JS/CSS 文件名加 hash,只要 HTML 还是旧的,引用的仍是老资源路径
HTML该用什么缓存策略
核心原则:让浏览器「频繁询问,但服务器快速响应」。推荐组合:
文章转信息图。将文章/笔记转化为手机可读的 HTML 信息图,自动匹配视觉风格。触发场景:文章转图、笔记转图、信息图、转小红书图、做张图、可视化这篇文章、文生图。
- 短时间强缓存 + 协商缓存:例如
Cache-Control: public, max-age=300(5 分钟),配合生成可靠的ETag - 或直接禁用强缓存,只留协商:
Cache-Control: no-cache(注意不是no-store),此时每次请求都带If-None-Match,服务器只需比对并返回 304 - 避免用
Expires:它依赖服务器与客户端时钟同步,出错概率高;Cache-Control优先级更高且语义清晰
如何生成靠谱的ETag来配合HTML缓存
ETag 不是随便拼个时间戳或随机数,它必须反映 HTML 内容的真实变化。常见错误是用模板渲染时间生成,结果导致「内容没变,ETag 却天天变」,协商缓存完全失效。
- 正确做法:对最终输出的 HTML 字符串做哈希(如
md5(htmlString)或sha256(htmlString)),作为ETag值 - 若 HTML 依赖后端数据(如用户昵称、未读消息数),需把关键变量纳入哈希输入,否则缓存会「假命中」
- Node.js 示例中可用
crypto.createHash('sha256').update(html).digest('hex');Laravel 可在视图渲染后 hook 生成 - 注意不要在开发环境启用 ETag,避免本地调试时被缓存干扰
图片等静态资源要和HTML分开对待
HTML 是门面,JS/CSS/图片是砖瓦。它们的缓存策略必须解耦:
- JS/CSS 文件名加 content-hash(如
app.a1b2c3.js),然后配Cache-Control: public, max-age=31536000, immutable - 图片用 CDN + 长期缓存(
max-age=31536000),但更新时必须换 URL(改文件名或加查询参数) - 绝对不要靠
meta http-equiv="Cache-Control"控制 HTML 缓存——它在现代浏览器中基本被忽略,且无法设置ETag
真正难的不是写对那几行响应头,而是想清楚「这个 HTML 在什么条件下才算变了」。一旦判断逻辑漏掉一个变量,缓存就变成陷阱。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










