html中meta标签设缓存基本无效,因主流浏览器忽略该写法;真正有效的是服务端响应头cache-control、内容哈希文件名及etag配合使用。

Cache-Control 配合内容哈希文件名和 ETag。
为什么根本不起作用
Chrome、Firefox、Safari 等主流浏览器完全忽略 HTML 中的 <meta http-equiv="Cache-Control" content="max-age=3600">。它不是规范支持的行为,只是早期误传的“技巧”。
- HTTP 缓存指令必须出现在响应头里,HTML 文档体内的 meta 是解析后才处理的内容,此时缓存决策早已完成
-
Expires同样不可靠:依赖客户端与服务端时钟严格同步,差几秒就可能让缓存提前失效或死锁 - CDN、公司代理等中间节点压根不解析 HTML,只认响应头
静态资源必须用 content hash + Cache-Control: immutable
只给 .js 或 .css 返回 Cache-Control: public, max-age=31536000 还不够——URL 不变,浏览器就不会发新请求,哪怕你已更新文件内容。
- 构建时生成带内容哈希的文件名,例如
main.a1b2c3.js,确保内容变 → URL 变 → 浏览器强制走新缓存流程 - 加上
immutable指令:Cache-Control: public, max-age=31536000, immutable,告诉浏览器“这个 URL 永远不会变内容”,F5 刷新也不发If-None-Match - 别用
private:除非该 JS 里硬编码了用户 token(严重不推荐),否则一律用public,让 CDN 和代理也能缓存
HTML 页面本身不能设长 max-age,得靠 no-cache + ETag
HTML 是动态入口,缓存太久会导致用户看不到更新(比如 CMS 改了文案,但页面仍显示旧版)。
- 给 HTML 响应头设
Cache-Control: no-cache——注意,这不是“不缓存”,而是强制走协商缓存流程 - 必须配
ETag(不是Last-Modified):Last-Modified精度只有秒级,且构建工具常重写修改时间戳,导致本该命中的缓存被误判为失效 -
ETag应基于文件内容生成(如"sha256-abc123"),内容不变则 ETag 不变;Nginx 默认开启,Apache 要确认未禁用FileETag
开发阶段最容易踩的坑:热更新和浏览器磁盘缓存打架
Webpack Dev Server 默认返回 Cache-Control: no-store,但如果你手动加了缓存头又没清掉浏览器磁盘缓存,就会出现“改了代码却没生效”的情况。
- F5 刷新会跳过强缓存但保留协商逻辑,所以即使配了 1 年缓存,F5 后仍可能触发一次 304 —— 这是规范行为,不是 bug
- 排查时打开 DevTools → Network → 找对应请求,看
Size列是否显示from disk cache或from memory cache,再核对响应头里的Cache-Control和ETag - 本地调试建议临时禁用缓存:DevTools → Network → 勾选
Disable cache,避免磁盘缓存干扰验证
Cache-Control 和 ETag 响应头——这两点缺一不可。其他都是锦上添花。前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











