学习PWA时Google DevTools中Service Worker离线模拟功能异常求助
问题描述
我正在学习开发PWA,发现Google DevTools无法正确模拟Service Worker的离线功能,核心需求是离线状态下展示offline.html页面。当前使用http-server ^0.9.0作为本地Web服务器,相关配置和Service Worker代码如下:
环境配置
package.json中的devDependencies:
"devDependencies": { "http-server": "^0.9.0" }
Service Worker代码(sw.js)
var CACHE_STATIC_NAME = 'static-v10'; var CACHE_DYNAMIC_NAME = 'dynamic-v2'; self.addEventListener('install', function(event) { console.log('[Service Worker] Installing Service Worker ...', event); event.waitUntil( caches.open(CACHE_STATIC_NAME) .then(function(cache) { console.log('[Service Worker] Precaching App Shell'); cache.addAll([ '/', '/index.html', '/offline.html', '/src/js/app.js', '/src/js/feed.js', '/src/js/promise.js', '/src/js/fetch.js', '/src/js/material.min.js', '/src/css/app.css', '/src/css/feed.css', '/src/images/main-image.jpg', 'https://fonts.googleapis.com/css?family=Roboto:400,700', 'https://fonts.googleapis.com/icon?family=Material+Icons', 'https://cdnjs.cloudflare.com/ajax/libs/material-design-lite/1.3.0/material.indigo-pink.min.css' ]); }) ) }); self.addEventListener('activate', function(event) { console.log('[Service Worker] Activating Service Worker ....', event); event.waitUntil( caches.keys() .then(function(keyList) { return Promise.all(keyList.map(function(key) { if (key !== CACHE_STATIC_NAME && key !== CACHE_DYNAMIC_NAME) { console.log('[Service Worker] Removing old cache.', key); return caches.delete(key); } })); }) ); return self.clients.claim(); }); self.addEventListener('fetch', function(event) { event.respondWith( caches.match(event.request) .then(function(response) { if (response) { return response; } else { return fetch(event.request) .then(function(res) { return caches.open(CACHE_DYNAMIC_NAME) .then(function(cache) { cache.put(event.request.url, res.clone()); return res; }) }) .catch(function(err) { return caches.open(CACHE_STATIC_NAME) .then(function(cache) { return cache.match('/offline.html'); }); }); } }) ); });
排查与解决步骤
1. 验证Service Worker的注册与缓存状态
- 打开DevTools的Application > Service Workers面板,确认:
- Service Worker处于
activated且running状态 - 在Cache Storage中找到
static-v10缓存,检查offline.html是否已被预缓存 - 如果缓存中没有目标文件,点击Service Workers面板的
Unregister按钮删除旧缓存,再刷新页面重新安装Service Worker
- Service Worker处于
2. 修复http-server的环境问题
http-server 0.9.0存在PWA兼容缺陷:
- 强制HTTPS环境:启动服务器时添加
-S参数启用HTTPS(需提前生成自签名证书):http-server -S -C cert.pem -K key.pem - 路径一致性检查:确保
offline.html的缓存路径与实际请求路径匹配。如果页面从子路径访问,需将缓存中的/offline.html调整为相对路径(如./offline.html)或完整路径
3. 优化Fetch事件逻辑
当前代码在所有请求失败时都返回offline.html,会导致非HTML资源加载异常,建议添加请求类型判断:
.catch(function(err) { // 仅当请求是HTML页面时返回离线页面 if (event.request.headers.get('accept').includes('text/html')) { return caches.open(CACHE_STATIC_NAME) .then(function(cache) { return cache.match('/offline.html'); }); } // 其他资源可返回默认错误或缓存中的替代资源 });
4. 规范DevTools离线模拟操作
- 必须在Application > Service Workers面板勾选
Offline选项,而非仅在Network面板开启离线 - 刷新页面时选择Empty Cache and Hard Reload(右键点击刷新按钮),避免浏览器使用内存缓存
5. 升级http-server版本
http-server 0.9.0版本过旧,存在已知的PWA兼容问题,建议升级到最新稳定版:
npm install http-server@latest --save-dev
内容的提问来源于stack exchange,提问作者Swapnil33
相关产品推荐
相关产品推荐

