如何移除加载整站缓存的Service Worker?解决子域名缓存遗留问题
解决www子域名旧Service Worker缓存问题的方案
方法1:部署"注销型"Service Worker到www子域名
既然能控制www子域名的服务器(已部署新网站),可以在该域名下部署一个极简的Service Worker脚本,注册后立即注销自身并清理缓存:
// sw-unregister.js self.addEventListener('install', (event) => { // 跳过等待,立即激活新Worker self.skipWaiting(); }); self.addEventListener('activate', (event) => { event.waitUntil( Promise.all([ // 清空所有旧缓存 caches.keys().then(cacheNames => { return Promise.all(cacheNames.map(cache => caches.delete(cache))); }), // 接管所有打开的页面并强制刷新 self.clients.claim().then(() => { self.clients.matchAll({ type: 'window' }).then(clients => { clients.forEach(client => client.navigate(client.url)); }); }), // 注销当前Service Worker self.registration.unregister() ]) ); });
同时在www域名的新网站首页加入注册该脚本的代码,确保能触发更新流程。
方法2:给Service Worker脚本设置强制不缓存的响应头
在www子域名的服务器上,给旧Service Worker的脚本文件(比如sw.js)添加严格的缓存禁止头,强制浏览器每次都请求最新脚本:
Cache-Control: no-cache, no-store, must-revalidate Pragma: no-cache Expires: 0
这样当浏览器检查Service Worker更新时,会直接拉取服务器上的新注销脚本,替代旧Worker。
方法3:在新网站页面加入自动注销Worker的逻辑
如果有用户偶然绕过缓存进入新网站(比如手动强制刷新),在www域名的新页面中加入这段JS,自动检测并注销旧Worker:
if ('serviceWorker' in navigator) { navigator.serviceWorker.getRegistrations().then(registrations => { registrations.forEach(reg => { reg.unregister().then(() => window.location.reload(true)); }); }); }
这段代码会清理当前域名下的所有Service Worker,然后强制刷新页面,确保用户看到最新内容。
方法4:引导用户手动操作(针对完全拦截请求的极端情况)
对于旧Worker完全拦截请求、连服务器都无法访问的用户,只能通过引导操作解决:在裸域名的正常页面上给出说明,比如告知用户"若访问www域名仍显示旧网站,请按Ctrl+Shift+Delete清除浏览器缓存,或打开开发者工具→应用→Service Workers中注销对应域名的Worker"。
核心注意事项
- Service Worker遵循域名隔离规则,裸域名的Worker无法操作www子域名的Worker,所有操作必须针对www子域名本身。
- 浏览器会定期(24小时内)自动检查Service Worker更新,结合上述方法可加速触发更新,避免用户等待过长时间。
内容的提问来源于stack exchange,提问作者Lukáš Řádek
相关产品推荐
相关产品推荐

