仅在 chrome 中重新启动时出现 Service Worker 错误:无法意外加载脚本

run*_*ace 5 javascript google-chrome google-chrome-devtools service-worker progressive-web-apps

问题

\n
    \n
  • 在 Firefox 上,可以安装以下 Service Worker,并且可以正常停止和启动。
  • \n
  • 在 Chrome 上,下面的测试服务工作人员安装罚款,工作完美,直到关闭并打开浏览器,或者在软件开发工具中单击“停止”,然后单击“开始”。
  • \n
\n

介绍

\n

我创建了一个服务工作人员,在本地使用 chrome 对其进行了调试,并且工作正常。我将其部署到网站上,并看到下图中的错误(仅在 Chrome 中,Firefox 工作正常):

\n
/static/core.jslib/sw.min.js:1 Failed to load the script unexpectedly\n/static/core.jslib/sw.min.js:1 Failed to load the script unexpectedly\n
Run Code Online (Sandbox Code Playgroud)\n

使用 Chrome,如果我单击启动服务工作线程,它会立即停止。对于 Firefox,它会运行一段时间然后停止(预期)。

\n

环境

\n
    \n
  • 操作系统:Ubuntu 20.04,Windows 10
  • \n
  • 浏览器\n
      \n
    • Chrome:版本 97.0.4692.99(官方版本)(64 位)
    • \n
    • 也出现在 Chromium 92.0.451598 上
    • \n
    \n
  • \n
  • Chrome 上不处于离线模式NetworkApplication
  • \n
  • 我唯一的线索是软件第一次安装时,它工作正常。但是,如果我关闭浏览器并重新打开它,我会看到这些错误并且软件会停止。听起来像是一个全局状态问题,即当工作程序再次启动时变量/对象不存在,但是我没有任何全局状态,正如您所看到的,只有几个函数。
  • \n
  • 没有扩展,全部禁用
  • \n
  • 在两台不同的电脑上尝试过,
  • \n
  • 下面的 sw.min.js 没有缩小,而是以未缩小的形式粘贴的。
  • \n
\n

在此输入图像描述

\n

我已经将我的服务人员简化为这样,所以现在我很确定这不是我的代码,而是 chromium 正在做的事情:

\n
/static/core.jslib/sw.min.js:1 Failed to load the script unexpectedly\n/static/core.jslib/sw.min.js:1 Failed to load the script unexpectedly\n
Run Code Online (Sandbox Code Playgroud)\n

注意:工作时,sw.min.js 文件会出现在源下(安装时),关闭并再次打开浏览器,然后不会显示:\n在此输入图像描述

\n

PS 在 Ubuntu 20.04 上运行。也许与 Linux 中 Service Worker 的存储位置有关。

\n

我什至添加了一个 fetch 调用来获取文件并在注册服务工作之前将其打印出来,以验证它可以访问该文件,而且总是没问题:

\n
Fetched /static/core.jslib/sw.min.js \nResponsebody: (...)bodyUsed: falseheaders: Headers\xc2\xa0{}ok: trueredirected: falsestatus: 200statusText: ""type: "basic"url: "https://www.demo..../static/core.jslib/sw.min.js"[[Prototype]]: Response\nswregister.min.50eb376e2ddc.js:1 SW: Registered - At scope https://www.demo..../\n/static/core.jslib/sw.min.js:1 Failed to load the script unexpectedly\n/static/core.jslib/sw.min.js:1 Failed to load the script unexpectedly\n
Run Code Online (Sandbox Code Playgroud)\n

错误顺序

\n

奇怪的是,当点击导航到其他地方时,就会出现错误。下面的控制台日志生成如下:

\n
    \n
  1. 清除控制台。
  2. \n
  3. 然后点击了一个链接
  4. \n
  5. 错误立即显示
  6. \n
  7. 然后它会显示有关导航的注释
  8. \n
  9. 然后它注册了 Service Worker。
  10. \n
\n

所以我不认为这是一个获取问题,我认为它是服务工作文件的内部存储,chrome 无法访问。

\n

在此输入图像描述

\n

Chrome Service Worker 内部结构

\n
chrome://serviceworker-internals/` shows the service worker:\nScope: https://www.demo..../\nRegistration ID: 287\nNavigation preload enabled: false\nNavigation preload header length: 4\nActive worker:\nInstallation Status: ACTIVATED\nRunning Status: STOPPED\nFetch handler existence: EXISTS\nScript: https://www.demo..../static/core.jslib/sw.min.js\nVersion ID: 649\nRenderer process ID: 0\nRenderer thread ID: -1\nDevTools agent route ID: -2\nLog:\n
Run Code Online (Sandbox Code Playgroud)\n

如果我点击start它会显示:

\n
Console: {"lineNumber":0,"message":"Failed to load the script unexpectedly",\n"message_level":3,"sourceIdentifier":1,"sourceURL":"https://www.demo.../static/core.jslib/sw.min.js"}\n
Run Code Online (Sandbox Code Playgroud)\n

而其他人的服务人员则启动并运行一段时间。

\n

响应头

\n

以下是响应标头sw.min.js

\n
# Here are the response headers for:\ndate: Tue, 25 Jan 2022 18:15:44 GMT\netag: "61f03d46-350"\nlast-modified: Tue, 25 Jan 2022 18:11:18 GMT\nserver: notepad.exe\nservice-worker-allowed: /\n
Run Code Online (Sandbox Code Playgroud)\n

清单.json

\n
{\n    "name": "Cube",\n    "short_name": "Cube",\n    "icons": [\n        {\n            "src": "/static/core.pwa/img/android-chrome-192x192.png",\n            "sizes": "192x192",\n            "type": "image/png",\n            "purpose": "any"\n        },\n        {\n            "src": "/static/core.pwa/img/android-chrome-512x512.png",\n            "sizes": "512x512",\n            "type": "image/png",\n            "purpose": "any"\n        },\n        {\n            "src": "/static/core.pwa/img/maskable_icon.png",\n            "sizes": "1024x1024",\n            "type": "image/png",\n            "purpose": "maskable"\n        }\n    ],\n    "theme_color": "#212121",\n    "background_color": "#ffffff",\n    "display": "standalone",\n    "start_url": "/"\n}\n
Run Code Online (Sandbox Code Playgroud)\n

run*_*ace 1

更新

Chromium 的人员发现这是 MIME 内容类型标头: https://bugs.chromium.org/p/chromium/issues/detail ?id=1292379#c17

在 nginx 中,我将标头更改为:

  • content-type: application/javascript; charset=utf-8

  • content-type: application/javascript

现在可以了!

原答案

注册服务工作者时,我将类型设置为模块。显然这在 Chrome 中意味着“重新启动时崩溃”。

const options = {
    scope: "/",
    // type: "module",  <-- needed to comment this out
};
const result = await navigator.serviceWorker.register(swPath, options);
Run Code Online (Sandbox Code Playgroud)

显然Chrome似乎不支持模块类型的服务工作者,当我检查支持表时,似乎有很好的支持。