调用 clients.claim() 是让新激活的 Service Worker 立即接管当前所有已打开页面的关键操作,否则默认只控制后续新打开的页面;需在 activate 事件中配合 event.waitUntil() 调用,并常与 skipWaiting 结合实现即时更新。

调用 clients.claim() 是让新激活的 Service Worker 立即接管当前所有已打开页面的关键操作,否则它默认只控制后续新打开的页面。
为什么需要 clients.claim()
Service Worker 的生命周期中,新版本安装后会进入 waiting 状态,待旧版本卸载(所有页面关闭)才自动激活。但若希望新 SW 在激活后立刻控制当前页面(比如热更新、强制刷新缓存逻辑),就必须在 activate 事件中显式调用 clients.claim()。
在 activate 事件中调用
必须在 activate 回调里调用,且通常配合 event.waitUntil() 确保异步完成:
self.addEventListener('activate', event => {
event.waitUntil(
clients.claim().then(() => {
console.log('New SW now controls all clients');
})
);
});
注意事项和常见问题
- 仅对当前作用域(scope)内的 clients 生效,跨 scope 页面不受影响
- 调用成功后,当前页面的
fetch事件将由新 SW 处理,但已有资源不会自动重载——需手动触发刷新或重新请求 - 如果页面已在加载中(如 HTML 已解析但 JS/CSS 还在 fetch),claim 不会中断现有网络请求,但后续请求都会走新 SW
- 不支持在非激活状态(如 installing 阶段)调用,否则报错
配合 skipWaiting 实现即时更新
单独 claim() 不够,还需在注册时或 install 阶段主动跳过 waiting:
// 注册时
navigator.serviceWorker.register('/sw.js').then(reg => {
reg.update(); // 触发更新检查
});
// 或在 SW 的 install 事件中
self.addEventListener('install', event => {
self.skipWaiting();
});
再结合 activate 中的 clients.claim(),才能实现“安装即生效、激活即接管”的完整流程。

















