cache.addAll 是“全有或全无”操作,任一 URL 请求失败(如404、跨域、网络中断)即整体 reject,不缓存任何资源;需确保所有 URL 可访问、同源/CORS、返回200–299状态码,并用 event.waitUntil() 包裹以保证安装完成。

cache.addAll 会静默忽略失败的 URL,不是所有请求都成功
cache.addAll 看起来是“全部添加”,但实际行为是:只要其中任意一个 fetch() 请求失败(如 404、跨域被拒、网络中断),整个 Promise 就会 reject,**不会缓存任何一个 URL**。它不是“尽力而为”,而是“全有或全无”。
常见错误现象:Uncaught (in promise) TypeError: Failed to fetch,但你只看到控制台报错,没意识到缓存完全没生效。
- 必须确保传入的 URL 列表里每个地址都可访问、同源(或已配 CORS)、且返回 200–299 状态码
- 动态生成的 URL(比如带时间戳参数)要提前确认有效性,
cache.addAll不做预检 - 如果想容错,得自己用
Promise.allSettled()+ 单个cache.put()替代
传给 cache.addAll 的必须是 Request 对象或 URL 字符串,不能混用
虽然文档说支持字符串,但实际中混用类型容易出问题——尤其当字符串是相对路径时,cache.addAll 会以当前脚本所在 Service Worker 文件的路径为基准解析,不是以 HTML 页面为准。
- 推荐统一用
new Request(url, { credentials: 'same-origin' })构造,显式控制凭据行为 - 避免直接传
'/api/data.json'这类相对路径;改用完整 URL 或location.origin + '/api/data.json' - 如果 URL 来自后端配置,务必先
encodeURI()处理含中文或空格的路径,否则可能抛TypeError: Invalid URL
cache.addAll 在 install 事件中使用最安全,但需注意 waitUntil
在 Service Worker 的 install 事件里调用 cache.addAll 是标准做法,但它返回的是 Promise,必须用 event.waitUntil() 包裹,否则 SW 可能跳过安装阶段、直接进入 waiting 状态。
立即学习“前端免费学习笔记(深入)”;
self.addEventListener('install', event => {
event.waitUntil(
caches.open('v1').then(cache =>
cache.addAll([
'/index.html',
'/styles/main.css',
'/scripts/app.js'
])
)
);
});
- 不加
event.waitUntil()→ 缓存逻辑可能被中断,且无任何提示 -
cache.addAll内部会自动调用fetch(),所以需要确保 SW 有网络权限(即不能在离线-only 模式下期望它工作) - 缓存体积大的资源(如图片、字体)时,注意 Chrome 对单次
cache.addAll的总大小有限制(约 5MB),超限会报QuotaExceededError
调试 cache.addAll 是否生效,别只看 network 面板
Network 面板里看不到缓存写入过程,cache.addAll 是纯 JS 操作,不触发可见请求。验证是否成功,得查 Cache Storage 面板(DevTools → Application → Cache Storage),或者用代码检查:
caches.open('v1').then(cache => cache.keys()).then(keys => {
console.log(keys.map(k => k.url)); // 输出已缓存的 URL 列表
});
- 如果
cache.keys()返回空数组,说明cache.addAll根本没执行成功,回头检查install事件是否被阻塞或 Promise 被 reject - 某些 URL 看似成功缓存,但实际响应体为空(比如服务器返回 204),这种也会被存入 cache,但后续
fetch()时可能出错 - Service Worker 更新后,旧 cache 不会自动清理,要手动
caches.delete(),否则容易误判“新资源没缓存进去”



















