You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

学习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

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 10:17:31