【问题标题】:PWA: No matching service worker detected. You may need to reload the pagePWA:未检测到匹配的服务人员。您可能需要重新加载页面
【发布时间】:2019-12-27 00:19:36
【问题描述】:

我收到此警告:

未检测到匹配的 Service Worker。您可能需要重新加载页面, 或检查当前页面的服务工作者是否也控制 清单中 URL 的开头。

我的服务人员正在工作的东西。

我什至尝试使用其他两个 URL,它们都使用 HTTPs。


现在我将向您展示我正在使用的代码:

site.webmanifest

{
    ...
    "start_url": "/",
    "display": "standalone"
    ...
}

为了创建我的 service-worker,我使用了 webpack 插件:WorkboxPlugin 与 Laravel Mix 结合:

webpack.mix.js

mix.webpackConfig({
    plugins: [
        build.jigsaw,
        build.browserSync(),
        build.watch(['source/**/*.md', 'source/**/*.php', 'source/**/*.scss', '!source/**/_tmp/*']),
        new WorkboxPlugin.GenerateSW({
            // these options encourage the ServiceWorkers to get in there fast
            // and not allow any straggling "old" SWs to hang around
            clientsClaim: true,
            skipWaiting: true,
        }),
    ],
    output: {
        publicPath: '/assets/build/', // fixes the output bug
    },
});

它创建 service-worker.js:

importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");

importScripts(
  "/assets/build/precache-manifest.cb67a9edd02323d8ea51560852b6cc0d.js"
);

workbox.core.skipWaiting();

workbox.core.clientsClaim();

self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});

使用 precache-manifest.js

self.__precacheManifest = (self.__precacheManifest || []).concat([
  {
    "revision": "4e264a665cf5133098ac",
    "url": "/assets/build//js/main.js"
  },
  {
    "revision": "4e264a665cf5133098ac",
    "url": "/assets/build/css/main.css"
  },
  {
    "url": "/assets/build/images/vendor/leaflet/dist/layers-2x.png?4f0283c6ce28e888000e978e537a6a56"
  },
  {
    "url": "/assets/build/images/vendor/leaflet/dist/layers.png?a6137456ed160d7606981aa57c559898"
  },
  {
    "url": "/assets/build/images/vendor/leaflet/dist/marker-icon.png?2273e3d8ad9264b7daa5bdbf8e6b47f8"
  }
]);

我应该如何处理这个警告?

【问题讨论】:

  • 愚蠢的问题,但您的调试控制台将文件显示为site.webmanifest,然后您将清单文件标记为site.manifest<link type="manifest" ... 中的路径是否指向正确的文件?
  • @JustinCollins 抱歉,这是一个错字。我链接到正确的清单文件
  • @JustinCollins 我可能有一个想法,我的范围设置不正确,但我不知道如何在没有“黑客”的情况下修复它(除了公众的服务人员之外文件夹并且不能更改服务器配置)。 (参考:stackoverflow.com/questions/35780397/…
  • 在我的情况下,我遇到了这个错误,因为 manifest.json 的 start_url 与加载的 url 不同(因为它有一个用户重定向;例如:domain.com/user1)

标签: service-worker progressive-web-apps workbox workbox-webpack-plugin


【解决方案1】:

我找到了解决方案!范围设置不正确。您需要了解,Service Worker 需要位于根文件夹中。

所以我的改变是:

webpack.mix.js

mix.webpackConfig({
    plugins: [
        build.jigsaw,
        build.browserSync(),
        build.watch(['source/**/*.md', 'source/**/*.php', 'source/**/*.scss', '!source/**/_tmp/*']),
        new WorkboxPlugin.GenerateSW({
            // these options encourage the ServiceWorkers to get in there fast
            // and not allow any straggling "old" SWs to hang around
            clientsClaim: true,
            skipWaiting: true,
            swDest: '../../service-worker.js', //Need to move the service-worker to the root
        }),
    ],
    output: {
        publicPath: '/assets/build/', // fixes the output bug
    },
});

现在我需要用新路径注册 service worker

if ('serviceWorker' in navigator) {
    window.addEventListener('load', () => {
        navigator.serviceWorker.register('/service-worker.js')
            .then(reg => {
                console.log('Registration succeeded. Scope is ' + reg.scope);
            })
            .catch(registrationError => {
                console.log('SW registration failed: ', registrationError);
            });
    });
}

【讨论】:

    【解决方案2】:

    这里最简单的解决方案是,就像之前的回答中提到的那样,将 service worker 文件与站点 webmanifest 文件一起放在根目录中。

    但是,如果您喜欢将资产分组到子目录中的人,那么您可以通过将scope 选项设置为/ 并将Service-Worker-Allowed HTTP 标头添加到响应中来手动设置范围。这样你的 service worker 文件就不需要在根目录了。

    参考https://w3c.github.io/ServiceWorker/#service-worker-script-response中的示例11

        // Set the scope to an upper path of the script location
        // Response included "Service-Worker-Allowed : /"
        navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).then(() => {
            console.log("Install succeeded as the max allowed scope was overriden to 
        '/'.");
        });
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-14
      • 1970-01-01
      • 2021-12-16
      • 2020-05-13
      • 2020-05-30
      • 2019-12-21
      • 2020-11-20
      • 2018-09-14
      相关资源
      最近更新 更多