PWA离线时怎么显示自定义的离线页面?

Mr.爱玲 阅读 49

我用React做了一个PWA应用,想在用户离线时展示一个友好的提示页面,但试了几次都不生效。我在service worker里缓存了/offline这个路由对应的页面,但断网后直接显示默认的浏览器错误页,根本没走到我的离线页面。

这是我在App.js里写的路由逻辑:

function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/offline" element={<OfflinePage />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  );
}

是不是光缓存页面还不够?还需要在fetch事件里手动拦截并返回离线页面吗?

我来解答 赞 5 收藏
二维码
手机扫码查看
1 条解答
怡萱
怡萱 Lv1
对,你说得对,光缓存页面确实不够。浏览器在离线时直接报错了,根本没机会让React Router来处理路由,所以你的/offline页面根本不会被加载。

核心问题在于service worker需要拦截fetch请求,在网络失败时主动返回缓存的离线页面。

在service worker里这样写:

self.addEventListener('fetch', (event) => {
// 只拦截页面导航请求
if (event.request.mode === 'navigate') {
event.respondWith(
fetch(event.request).catch(() => {
// 网络请求失败时,返回缓存的离线页面
return caches.match('/offline.html');
})
);
}
// 其他资源正常走缓存策略
});


几点要注意:

1. 离线页面文件名最好用offline.html,别用React路由的路径。因为service worker拦截的是实际的网络请求,浏览器发起的是对/offline.html的请求,不是/offline这个路由。

2. 确保在service worker的install事件里提前缓存这个离线页面:

self.addEventListener('install', (event) => {
event.waitUntil(
caches.open('your-cache-name').then((cache) => {
return cache.addAll(['/offline.html']);
})
);
});


3. 如果你用的是Create React App或者Vite创建的PWA,它们的默认service worker可能已经内置了这个逻辑,你可以检查一下sw.js或者workbox的配置。

这样断网的时候,fetch会失败,catch捕获到错误后就会返回你缓存的offline.html,浏览器就能正常显示你的自定义离线页面了。
点赞
2026-03-17 14:04