现状描述

btool在线工具使用vite-plugin-pwa打包,支持离线使用。但是网站博客采用的是hexo打包生成的静态网站。在挂载到btool在线工具主页时,如果不过滤地址/blog的话,浏览器直接被ServiceWorker拦截跳转到404页面。

分析原因

分析插件vite-plugin-pwa是通过谷歌workbox来封装实现的ServiceWorker功能。

通过分析workbox的参数配置,及打包后的sw.js。workbox-routing 路由模块

import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';

// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
  allowlist: [new RegExp('/blog/')],
  denylist: [new RegExp('/blog/restricted/')],
});
registerRoute(navigationRoute);

每当用户通过浏览器访问您的网站时,对该网页的请求都将是导航请求,并且系统将提供缓存的网页 /app-shell.html。(注意:您应该通过 workbox-precaching 或您自己的安装步骤缓存该页面。)

默认情况下,这将响应所有导航请求。如果您想限制其响应部分网址,可以使用 allowlist 和 denylist 选项来限制哪些页面将与此路由匹配。

需要注意的是,如果网址同时存在于 allowlist 和 denylist 中,则 denylist 胜出。

解决方式

我们需要找到vite-plugin-pwa插件对应workbox NavigationRoute denylist的参数配置。

VitePWA({
  workbox: {
    navigateFallbackDenylist: [/^\/blog/]
  }
})

根据官方文档说明,要排除服务工作者拦截的某些路由,只需在workbox 的navigateFallbackDenylist选项中使用regex列表添加这些路由即可。