Service Worker 调试方法与工具详解
Service Worker 运行在浏览器后台,调试相对复杂。掌握正确的调试方法和工具对于开发至关重要。
Chrome DevTools 调试
1. Application 面板
Chrome DevTools 的 Application 面板是调试 Service Worker 的主要工具。
shellDevTools → Application → Service Workers
主要功能:
- 查看已注册的 Service Worker
- 查看当前状态(activated, installing, waiting 等)
- 手动触发更新(Update)
- 注销 Service Worker(Unregister)
- 模拟离线环境(Offline checkbox)
- 绕过网络(Bypass for network)
2. 网络面板调试
javascript// 查看 Service Worker 拦截的请求 // DevTools → Network → 查看 Size 列 // (from ServiceWorker) 表示从缓存返回 // (from disk cache) 表示从磁盘缓存返回 // (from memory cache) 表示从内存缓存返回
3. Console 面板
javascript// Service Worker 中的 console.log 会显示在 DevTools Console // 注意:需要勾选 "Preserve log" 以保留刷新前的日志 // 查看当前 Service Worker 状态 navigator.serviceWorker.ready.then(registration => { console.log('Service Worker 状态:', registration); });
常用调试技巧
1. 强制更新 Service Worker
javascript// 方法1:手动更新 navigator.serviceWorker.getRegistration().then(reg => { reg.update(); }); // 方法2:硬刷新(Ctrl+Shift+R 或 Cmd+Shift+R) // 会绕过 Service Worker,安装新版本 // 方法3:DevTools Application 面板点击 Update
2. 查看缓存内容
javascript// 查看所有缓存 async function inspectCaches() { const cacheNames = await caches.keys(); console.log('缓存列表:', cacheNames); for (const name of cacheNames) { const cache = await caches.open(name); const requests = await cache.keys(); console.log(`缓存 ${name} 内容:`, requests.map(r => r.url)); } } inspectCaches();
3. 清除缓存
javascript// 清除所有缓存 async function clearAllCaches() { const cacheNames = await caches.keys(); await Promise.all(cacheNames.map(name => caches.delete(name))); console.log('所有缓存已清除'); } // 清除特定缓存 async function clearCache(cacheName) { await caches.delete(cacheName); console.log(`缓存 ${cacheName} 已清除`); }
4. 模拟离线环境
javascript// 方法1:DevTools Network 面板 // 选择 "Offline" 或设置自定义网络条件 // 方法2:代码中检测 window.addEventListener('offline', () => { console.log('进入离线模式'); }); // 方法3:手动触发离线状态 // navigator.connection 可以查看网络状态 console.log('网络状态:', navigator.connection);
5. 调试 Fetch 事件
javascript// sw.js 中添加详细日志 self.addEventListener('fetch', event => { console.log('Fetch 请求:', { url: event.request.url, method: event.request.method, mode: event.request.mode, destination: event.request.destination }); event.respondWith( caches.match(event.request).then(response => { if (response) { console.log('缓存命中:', event.request.url); return response; } console.log('缓存未命中,请求网络:', event.request.url); return fetch(event.request); }) ); });
高级调试技术
1. 使用 Chrome 的 Service Worker 内部页面
shellchrome://serviceworker-internals/
可以查看所有 Service Worker 的详细信息,包括:
- 注册信息
- 控制台日志
- 网络请求
- 存储使用情况
2. 使用 Workbox 调试
如果使用 Workbox,可以启用详细日志:
javascript// 启用 Workbox 调试 workbox.setConfig({ debug: true }); // 查看 Workbox 日志 workbox.core.setLogLevel(workbox.core.LOG_LEVELS.debug);
3. 断点调试
javascript// 在 Service Worker 代码中设置 debugger self.addEventListener('fetch', event => { debugger; // DevTools 会在这里暂停 event.respondWith( caches.match(event.request).then(response => { return response || fetch(event.request); }) ); });
4. 使用 console.table 查看缓存
javascriptasync function logCacheContents() { const cache = await caches.open('my-cache'); const requests = await cache.keys(); const tableData = await Promise.all( requests.map(async request => { const response = await cache.match(request); return { URL: request.url, Status: response.status, Type: response.headers.get('content-type'), Size: response.headers.get('content-length') }; }) ); console.table(tableData); }
常见问题排查
1. Service Worker 未注册
javascript// 检查浏览器支持 if ('serviceWorker' in navigator) { navigator.serviceWorker.register('/sw.js') .then(reg => console.log('注册成功:', reg)) .catch(err => console.error('注册失败:', err)); } else { console.error('浏览器不支持 Service Worker'); }
2. HTTPS 问题
javascript// 检查是否 HTTPS(localhost 除外) if (location.protocol !== 'https:' && location.hostname !== 'localhost') { console.error('Service Worker 需要 HTTPS 环境'); }
3. 缓存未更新
javascript// 确保每次更新 Service Worker 时更改缓存名称 const CACHE_NAME = 'my-app-v2'; // 更新版本号 self.addEventListener('activate', event => { event.waitUntil( caches.keys().then(cacheNames => { return Promise.all( cacheNames .filter(name => name !== CACHE_NAME) .map(name => caches.delete(name)) ); }) ); });
4. 跨域资源缓存问题
javascript// CORS 资源需要特殊处理 self.addEventListener('fetch', event => { if (event.request.mode === 'cors') { // 跨域请求使用 no-cors 模式缓存 event.respondWith( fetch(event.request, { mode: 'no-cors' }) .then(response => { return caches.open('cors-cache').then(cache => { cache.put(event.request, response.clone()); return response; }); }) ); } });
调试清单
开发阶段检查项
- Service Worker 成功注册
- Install 事件正常触发
- 静态资源正确缓存
- Fetch 事件正确拦截
- 缓存策略按预期工作
- Activate 事件清理旧缓存
- 离线功能正常
生产环境检查项
- Service Worker 文件不被缓存
- 缓存版本控制正确
- 更新机制正常工作
- 错误处理完善
- 降级方案有效
推荐工具
| 工具 | 用途 |
|---|---|
| Chrome DevTools | 主要调试工具 |
| Workbox | Service Worker 库,带调试功能 |
| Lighthouse | PWA 审核和性能分析 |
| PWA Builder | 验证 PWA 配置 |
| Web Server for Chrome | 本地 HTTPS 测试 |
调试最佳实践
- 使用 Chrome DevTools:充分利用 Application 面板
- 添加详细日志:开发和生产环境使用不同日志级别
- 版本控制:每次更新更改缓存名称
- 测试离线:定期测试离线功能
- 监控错误:使用错误追踪服务监控 Service Worker 错误