html缓存机制关键在于分清缓存主体与触发逻辑:cache-control优先级高于expires,max-age=0触发协商缓存而非禁用缓存,no-cache需验证、no-store才禁止存储;html长期缓存会导致js更新不可见,应通过文件哈希+短时效cache-control(如max-age=60)解决;meta标签被现代浏览器忽略,service worker缓存仅在http缓存失效后生效。

搞懂 HTML 缓存机制,关键不是背指令,而是分清「谁在缓存」「怎么触发缓存」「缓存失效时浏览器到底做了什么」。所有混乱都来自混淆 HTTP 层缓存和前端 JS 可控缓存(如 CacheStorage),或误以为 <meta http-equiv> 能起作用。
Cache-Control 和 Expires 到底谁说了算
优先级明确:Cache-Control 完全覆盖 Expires。只要响应头里有 Cache-Control,浏览器就无视 Expires 字段——哪怕 Expires 写的是明年,Cache-Control: no-cache 一出现,立刻走协商流程。
常见误区:
-
max-age=0≠ 不缓存:它只是让强缓存立即过期,但后续仍可能走304协商缓存 -
no-cache不是“不存”,而是“每次用前必须验证”;no-store才是真·禁止任何存储 -
public允许 CDN 和浏览器共用缓存;private只允许浏览器存,代理/CDN 必须跳过
为什么改了 JS 文件,HTML 页面还是加载旧版本
根本原因:HTML 文件(通常是 index.html)被长期缓存,而它引用的 bundle.js 路径没变,浏览器就复用旧 HTML + 旧缓存的 JS —— 即使你已部署新 JS,用户也看不到。
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
解法不是清用户缓存,而是打破缓存键一致性:
- 构建时对 JS/CSS 文件名加哈希,如
app.a1b2c3.js,确保 HTML 引用路径变更 - 服务端给
index.html设置短缓存:Cache-Control: public, max-age=60(1 分钟),避免锁死 - 绝对不要用
<meta http-equiv="Cache-Control">:现代浏览器(Chrome/Firefox/Safari)全部忽略它
DevTools 里怎么看缓存是否生效
打开 Network 面板后,只看三列:Status、Size、Headers:
-
Status是304 Not Modified→ 协商缓存命中,服务器确认没变,复用本地副本 -
Size显示from memory cache或from disk cache→ 强缓存命中,根本没发请求 -
Size显示具体字节数 +Status 200→ 强缓存失效,重新下载(注意:普通刷新 F5 会跳过强缓存但保留协商缓存) -
Cache-Control值在 Response Headers 里,不是 Request Headers;如果没看到,说明服务端根本没设置
Service Worker 的缓存和 HTTP 缓存是两套系统
很多人以为装了 Service Worker 就能“接管一切缓存”,其实它和 HTTP 缓存并行且有明确优先级:
- HTTP 缓存(
Cache-Control)优先级更高:只要资源还在强缓存有效期,fetch 请求连 Service Worker 的fetch事件都不会触发 - Service Worker 的
cache.match()只在 HTTP 缓存失效或被 bypass(比如加了cache: 'reload')时才真正起作用 - 想让 SW 真正兜底,得配合服务端把关键资源设为
Cache-Control: no-store或极短max-age,逼请求进 SW
最易被忽略的一点:HTML 页面本身若被强缓存锁死(比如 max-age=31536000),Service Worker 脚本更新都可能失败——因为浏览器不会重新拉取新的 sw.js,除非 HTML 先更新。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










