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

React PWA离线模式无法运行问题及sw-toolbox集成咨询

解决React PWA离线加载问题及sw-toolbox集成方法

一、先修复现有Service Worker的问题

你的Service Worker存在几个关键错误,直接导致离线加载失败:

  1. cache.addAll()参数使用错误
    cache.addAll()仅接受单个资源数组作为参数,你传入多个数组的写法无效,只有第一个urlsToCache会被缓存,其余资源都未加入缓存池。

  2. 无效的资源路径
    像/shirt-trouser/shirts/.jpeg这类路径缺少具体文件名,无法匹配实际图片资源,缓存这类路径没有意义,必须替换为真实的图片文件路径(比如/shirt-trouser/shirts/blue-shirt.jpeg)。

  3. 缺少fetch事件拦截逻辑
    Service Worker安装完成后,必须监听fetch事件来拦截网络请求,从缓存返回资源;否则离线时浏览器仍会发起网络请求,最终因无网络导致失败。

修正后的基础Service Worker代码

let CACHE_NAME = 'my-site-cache-v1';

// 合并所有需要预缓存的资源为一个数组
const urlsToCache = [
  '/',
  '/index.html',
  // 替换为实际存在的图片路径,示例:
  // '/shirt-trouser/shirts/shirt1.jpeg',
  // '/shirt-trouser/shirts/shirt2.jpg',
  '/config.js',
  '/index.js',
  '/App.js',
  '/components/BabylonAvatar.js',
  '/components/SceneComponent.js',
  '/avatar/newformalwalk13.glb'
];

// 安装阶段:预缓存资源
self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        return cache.addAll(urlsToCache);
      })
      // 跳过等待,立即激活新的Service Worker
      .then(() => self.skipWaiting())
  );
});

// 激活阶段:清理旧缓存
self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.filter(function(cacheName) {
          return cacheName !== CACHE_NAME;
        }).map(function(cacheName) {
          return caches.delete(cacheName);
        })
      );
    })
  );
});

// 拦截fetch请求,优先从缓存返回资源
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        // 缓存有资源则直接返回,否则发起网络请求
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

二、sw-toolbox与React的集成方法

sw-toolbox可以简化Service Worker的缓存策略管理,具体步骤如下:

1. 安装sw-toolbox

在React项目中执行安装命令:

npm install sw-toolbox --save

2. 创建Service Worker文件(如sw.js)

引入sw-toolbox并配置不同资源的缓存策略:

importScripts('node_modules/sw-toolbox/sw-toolbox.js');

// 设置缓存名称前缀
toolbox.options.cache.name = 'my-react-pwa-cache';

// 页面资源:缓存优先,同时后台更新缓存
toolbox.router.get('/', toolbox.cacheFirst);
toolbox.router.get('/index.html', toolbox.cacheFirst);

// JS/CSS资源:网络优先,网络失败则用缓存
toolbox.router.get('/*.js', toolbox.networkFirst);
toolbox.router.get('/*.css', toolbox.networkFirst);

// 图片资源:缓存优先,设置缓存上限和有效期
toolbox.router.get('/shirt-trouser/*/*.{jpeg,jpg,png}', toolbox.cacheFirst, {
  cache: {
    maxEntries: 50, // 最多缓存50个图片资源
    maxAgeSeconds: 30 * 24 * 60 * 60 // 缓存有效期30天
  }
});

// 3D模型资源:缓存优先
toolbox.router.get('/avatar/*.glb', toolbox.cacheFirst);

// 激活时接管所有客户端
self.addEventListener('activate', () => {
  self.clients.claim();
});

3. 在React项目中注册Service Worker

在React入口文件(如index.js)中添加注册逻辑:

if ('serviceWorker' in navigator) {
  window.addEventListener('load', () => {
    navigator.serviceWorker.register('/sw.js')
      .then(registration => {
        console.log('Service Worker registered: ', registration);
      })
      .catch(error => {
        console.log('Service Worker registration failed: ', error);
      });
  });
}

4. 配置打包工具(以Create React App为例)

将sw.js放在项目的public目录下,确保构建时会被复制到build目录;若使用自定义Webpack配置,可通过copy-webpack-plugin将sw.js和node_modules/sw-toolbox/sw-toolbox.js复制到构建输出目录。

三、离线功能测试注意事项

  • 确保所有需离线访问的资源路径正确,避免遗漏或错误路径。
  • 使用Chrome DevTools的Application > Service Workers勾选Offline选项,模拟离线环境测试。
  • 修改Service Worker后,需更新CACHE_NAME(如改为my-site-cache-v2),触发新的安装和激活流程,替换旧缓存。

内容的提问来源于stack exchange,提问作者Asha Datla

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:42:44