cache api只能在service worker或worklet线程中使用,页面主线程调用caches.open()会因上下文受限而抛出securityerror或返回undefined。

Cache API 不是“开了就能用”的黑盒,它必须和 Service Worker 绑定运行,且所有操作都得在 self 上下文中进行——直接在页面脚本里调用 caches.open() 会失败,因为非 Worker 环境不支持该 API。
为什么在页面里调用 caches.open() 报错?
浏览器明确限制 Cache API 只能在 Service Worker(或 Worklet)线程中使用。页面主线程里执行 caches.open('my-cache') 会抛出 SecurityError: caches is not available in this context 或直接返回 undefined。
- Service Worker 必须先注册成功(
navigator.serviceWorker.register('/sw.js')),且 sw.js 文件需与页面同源、通过 HTTPS(或 localhost)提供 - 注册后,浏览器会在后台启动 Worker,但不会立即接管当前页面——除非你在
activate事件中显式调用self.clients.claim() - 调试时可在 Chrome DevTools 的 Application → Service Workers 面板勾选 “Update on reload” 并强制刷新,确保新版本被安装并激活
caches.open() 后为什么缓存没写进去?
常见原因是忽略了 event.waitUntil() 包裹异步操作,导致 install 事件提前结束,缓存被丢弃。
-
caches.open()返回 Promise,必须用event.waitUntil()包住整个链式调用,否则 Worker 认为 install 已完成,后续cache.addAll()可能被中断 - 资源列表中任何一项 404、跨域无 CORS 响应头、或非 GET 请求,都会让
cache.addAll()整体失败,缓存不会写入 - 不要在
install中尝试缓存动态接口(如/api/user?uid=123),URL 必须是确定的静态路径
fetch 事件中 cache.match() 总是返回 undefined?
匹配失败往往不是代码写错,而是请求对象被重复消费或匹配条件太严格。
-
Request对象只能读取一次 body,若你先用它调了cache.match(request),再传给fetch(request)就会报错;必须用request.clone()分出副本 - 默认情况下
cache.match()区分 URL 参数、HTTP 方法、请求头;如果服务端对/logo.png?v=2和/logo.png返回相同内容,就得加选项:cache.match(request, { ignoreSearch: true }) - 确保缓存时存的是有效响应(status 200–299)。如果
fetch()返回 304 或 404,cache.put()不会报错但也不会真正写入
如何安全清理旧缓存避免磁盘占满?
浏览器不会自动删旧缓存,全靠你在 activate 事件里手动清理——这步漏掉,缓存只会越积越多。
- 每次升级 Service Worker,建议把缓存名带上版本号,比如
'static-v3',并在activate中只保留当前版本名数组里的缓存 - 清理逻辑必须用
event.waitUntil()包住,否则可能被中断;caches.delete()返回 Promise,记得用Promise.all()并行处理多个缓存 - 别依赖
navigator.storage.estimate()做精确容量判断——它的quota是估算值,且不同浏览器返回差异大;更稳妥的做法是按时间或版本做定期清理
最常被忽略的一点:缓存的 Request → Response 键值对是强耦合的,Response 里的 headers、status、body 都会被序列化存储。如果你在 fetch 事件中修改了响应(比如注入 CSP header),又想缓存它,必须用 new Response(body, { status, headers }) 显式构造新 Response,再传给 cache.put() —— 直接 cache.put(request, response) 会缓存原始未修改版本。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











