cache api 只能在 service worker 全局作用域中使用,页面脚本中调用会因 caches 未定义而报 referenceerror;所有操作必须在 sw.js 的 install/fetch 事件中完成,并注意路径、状态码、request.clone() 和版本清理等细节。

Cache API 不能在 HTML 页面脚本里直接调用,必须通过 Service Worker 注册并控制;否则 caches.open() 会报 ReferenceError: caches is not defined。
为什么在 <script></script> 里写 caches.open() 一定失败
浏览器把 caches 对象严格限制在 Service Worker 全局作用域内。HTML 中的脚本运行在 window 上下文,caches 根本未定义——不是权限问题,是环境缺失。哪怕你把 sw.js 已注册成功,页面脚本也依然无法访问它。
- 错误现象:
ReferenceError: caches is not defined,控制台立刻报错,脚本中断 - 常见误操作:在页面
<script></script>中尝试预热缓存、手动调用caches.keys()查看已有缓存 - 正确路径:所有 Cache API 操作(
open、addAll、match)都必须写在sw.js文件中,并由navigator.serviceWorker.register('sw.js')触发执行
静态资源二次加载快的关键:install 阶段预加载 + fetch 阶段拦截匹配
“二次加载快”不是靠页面主动读缓存,而是靠 Service Worker 在用户发起请求前就存好,并在请求到达时自动返回缓存响应。核心是两步闭环:
-
install事件中用event.waitUntil(caches.open('static-v1').then(cache => cache.addAll([...]))预加载关键静态资源(如/index.html、/main.css、/app.js) -
fetch事件中用caches.match(event.request, { ignoreSearch: true })匹配请求,命中则event.respondWith(response)直接返回,不走网络 - 注意
ignoreSearch: true:否则/logo.png?v=2和缓存的/logo.png不匹配;ignoreMethod: true可让 HEAD 请求也命中 GET 缓存
容易踩的坑:路径、状态码、request 复用
预加载失败或缓存不生效,90% 出在细节上:
-
cache.addAll()里的路径必须是相对根路径(如'/styles/main.css'),不能是相对当前 HTML 的路径(如'./styles/main.css') - 所有 URL 必须能被浏览器以 GET 方式成功请求,返回 200–299 状态码;404 或跨域拒绝会导致整个
install失败 - 不能把动态接口(如
/api/user?uid=123)塞进addAll()—— 它只适合确定不变的静态资源 -
fetch事件中若需同时读缓存和发网络(stale-while-revalidate),必须对event.request调用clone(),否则原 request 会被消耗一次后不可再用
版本命名与 activate 清理决定是否真正“平滑升级”
缓存名带版本(如 'static-v2')只是第一步,不清理旧缓存,用户永远拿不到新资源:
- 在
activate事件中遍历caches.keys(),用caches.delete()删除非当前版本的缓存(如key !== 'static-v2') - 必须加
event.waitUntil(),否则清理可能被中断 - 清理时机很重要:
activate发生在旧 Service Worker 完全退出后,此时新 SW 才接管 fetch,避免请求被旧缓存干扰
真正卡住性能的往往不是 API 不会用,而是 install 里路径写错一个斜杠、fetch 里忘了 clone()、或者版本更新后没清理旧缓存——这些点不显眼,但一出错就整个离线策略失效。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!











