Cache API不能在HTML中直接使用,必须由Service Worker控制;HTML中调用caches.open()会报ReferenceError,因caches仅在Service Worker全局作用域可用,页面脚本运行于window上下文且caches未定义。

Cache API 不能在 HTML 中直接使用 —— 它必须由 Service Worker 脚本控制,且 HTML 文件本身只是被缓存的对象,不是执行缓存的主体。
为什么 HTML 里写 caches.open() 会报错
浏览器限制 caches 对象仅在 Service Worker 全局作用域可用;HTML 中的普通脚本执行在 window 上下文,caches 是未定义的。试图在 <script> 标签里调用会直接抛出 ReferenceError: caches is not defined。
- Service Worker 是唯一能访问
caches、self.clients、self.skipWaiting()等离线能力 API 的 JS 环境 - HTML 页面可通过
navigator.serviceWorker.register('sw.js')注册它,但注册 ≠ 执行缓存逻辑 - 即使 HTML 带了
<meta http-equiv="Cache-Control" content="max-age=3600">,那也只影响 HTTP 缓存,和 Cache API 无关
静态资源缓存必须在 Service Worker 的 install 事件中完成
预加载关键静态资源(如 /index.html、/main.css、/app.js)是离线可用的前提。不放在这里,后续 fetch 拦截时就无响应可返回。
- 必须用
event.waitUntil()包裹caches.open().then(cache => cache.addAll([...])),否则安装可能提前结束,缓存失败 -
cache.addAll()内部是并发请求,任一失败会导致整个 install 失败(返回 reject),所以路径必须全为相对根路径、全部可 GET、全部返回 200–299 - 不要把动态接口(如
/api/user?uid=123)塞进addAll()—— URL 必须静态确定,否则请求会 404 或被跨域拦截
示例片段:
立即学习“前端免费学习笔记(深入)”;
使用 PptxGenJS 和 Python 解析,将结构化的 HTML/CSS 幻灯片内容转换为原生、可编辑的 PowerPoint(.pptx)演示文稿。
self.addEventListener('install', event => {
event.waitUntil(
caches.open('static-v1').then(cache =>
cache.addAll([
'/',
'/index.html',
'/styles/main.css',
'/scripts/app.js',
'/images/logo.png'
])
)
);
});
缓存后怎么让页面真正读到它?靠 fetch 事件拦截 + respondWith
install 阶段只是“存进去”,用户访问时仍会发真实网络请求。要让它从缓存取,必须在 fetch 事件中主动匹配并返回。
-
caches.match(event.request)是核心匹配动作,但它默认严格比对 URL 参数、method、headers —— 若你缓存了/logo.png,但请求带?v=2,默认不命中 - 常见修复:加
{ ignoreSearch: true }忽略 query string,或{ ignoreMethod: true }(GET/HEAD 视为等价) - 务必用
event.request.clone()分副本:先 match 再 fetch,否则 request body 被消费一次后第二次读取为空 - 不要漏掉 fallback:match 返回
undefined时,应return fetch(event.request)走网络,否则离线白屏
示例片段:
立即学习“前端免费学习笔记(深入)”;
self.addEventListener('fetch', event => {
event.respondWith(
caches.match(event.request, { ignoreSearch: true }).then(response => {
return response || fetch(event.request);
})
);
});
验证缓存是否生效,别信 Network 面板的 “from cache”
Network 面板显示的 from cache 是 HTTP 缓存(disk/memory),和 Cache API 完全无关。真要看 Cache API 是否写入成功,必须去 DevTools → Application → Cache Storage。
- 打开后能看到你命名的缓存(如
static-v1),点开看条目列表是否包含你期望的路径 - 点某条目,右侧看
Status: 200 OK和Preview是否可读 —— 如果 Preview 空白,大概率是响应体 stream 已被读尽或跨域没配Access-Control-Allow-Origin - 删缓存别只点刷新按钮:选中缓存名 → 右键 →
Delete;清空全站要用 Application → Storage → 勾选Cache storage→Clear site data
最易忽略的一点:Service Worker 更新后,旧缓存不会自动清理,activate 事件里必须显式 caches.delete() 旧版本缓存,否则磁盘越积越多,且新旧缓存可能冲突。


















