1

我有一个创建反应应用程序项目,该项目使用反应路由器和工作箱作为服务人员。

它由 IIS 托管,为了使页面重新加载工作,我已将此 web.config 添加到我的公共目录中。

<?xml version="1.0"?>
<configuration>
    <system.webServer>
        <rewrite>
            <rules>
                <rule name="React Routes" stopProcessing="true">
                    <match url=".*" />
                    <conditions logicalGrouping="MatchAll">
                        <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
                        <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
                        <add input="{REQUEST_URI}" pattern="^/(api)" negate="true" />
                    </conditions>
                    <action type="Rewrite" url="/" />
                </rule>
            </rules>
        </rewrite>
    </system.webServer>
</configuration>

这意味着它将始终从根(基本入口点)为应用程序提供服务。这部分效果很好。这个解决方案是必需的,因为我使用BrowserRouter(反应路由器)来获取漂亮的 url。

但是,我也激活了服务人员。我使用工作箱来帮助服务人员。

这是我的工作箱构建脚本

const workboxBuild = require("workbox-build");

const buildSW = () => {
  // The build is expected to fail if the
  // sw install rules couldn't be generated.
  // Add a catch block to handle this scenario.
  return workboxBuild
    .injectManifest({
      swSrc: "src/sw-custom.js", // custom sw rule

      swDest: "build/sw.js", // sw output file (auto-generated

      globDirectory: "build",

      globPatterns: ["**/*.{js,css,html,jpg,jpeg,gif,png,svg}"],

      maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
    })
    .then(({ count, size, warnings }) => {
      warnings.forEach(console.warn);
      console.info(`${count} files will be precached,
                  totaling ${size / (1024 * 1024)} MBs.`);
    });
};

buildSW();

最后是我的工作箱代码

if ("function" === typeof importScripts) {
    importScripts(
      "https://storage.googleapis.com/workbox-cdn/releases/5.1.3/workbox-sw.js"
    );
  
    // Global workbox
    if (workbox) {
      console.log("Workbox is loaded");
    
      //`generateSW` and `generateSWString` provide the option
      // to force update an exiting service worker.
      // Since we're using `injectManifest` to build SW,
      // manually overriding the skipWaiting();
      self.addEventListener("install", (event) => {
        // self.skipWaiting();
        // window.location.reload();
      });

      self.addEventListener('message', (event) => {
        if (event.data && event.data.type === 'SKIP_WAITING') {
          self.skipWaiting();
        }
      });
  
      // Manual injection point for manifest files.
      // All assets under build/ and 5MB sizes are precached.
      workbox.precaching.precacheAndRoute([]);
  
      // Font caching
      workbox.routing.registerRoute(
        new RegExp("https://fonts.(?:.googlepis|gstatic).com/(.*)"),
        new workbox.strategies.CacheFirst({
          cacheName: "googleapis",
          plugins: [
            new workbox.expiration.ExpirationPlugin({
              maxEntries: 100,
              maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
            }),
          ],
        })
      );
  
      // Image caching
      workbox.routing.registerRoute(
        /\.(?:png|gif|jpg|jpeg|svg)$/,
        new workbox.strategies.CacheFirst({
          cacheName: "images",
          plugins: [
            new workbox.expiration.ExpirationPlugin({
              maxEntries: 1000,
              maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
            }),
          ],
        })
      );
  
      // JS, CSS caching
      workbox.routing.registerRoute(
        /\.(?:js|css)$/,
        new workbox.strategies.StaleWhileRevalidate({
          cacheName: "static-resources",
          plugins: [
            new workbox.expiration.ExpirationPlugin({
              maxEntries: 100,
              maxAgeSeconds: 60 * 24 * 60 * 60, // 60 Days
            }),
          ],
        })
      );
    } else {
      console.error("Workbox could not be loaded. No offline support");
    }
  }

现在是实际问题: 当我离线时,如果我在起始页(url:/)上重新加载页面仍然可以正常工作但是,如果我在 /foo/bar 之类的子页面上并重新加载页面我只是在 chrome 中获取“页面离线”。无论我在哪个 url 上使用 react 路由器,如何让我的 service worker 离线工作?

4

0 回答 0