ServiceWorkerContainer: register() 方法

安全上下文:此功能仅在安全上下文(HTTPS)中可用,且在某些或所有支持的浏览器中可用。

注意:此功能在Web Workers中可用。

register() 方法是 ServiceWorkerContainer 接口的方法,用于为给定的 scriptURL 创建或更新 ServiceWorkerRegistration

如果成功,服务工作者注册会将提供的脚本 URL 绑定到一个作用域,该作用域随后用于导航匹配。您可以从受控页面无条件地调用此方法。也就是说,您不需要首先检查是否存在活动的注册。

语法

js
register(scriptURL)
register(scriptURL, options)

参数

scriptURL

服务工作者脚本的 URL。已注册的服务工作者文件需要具有有效的JavaScript MIME 类型

options 可选

包含注册选项的对象。当前可用的选项包括

scope

一个字符串,表示定义服务工作者注册作用域的 URL;即服务工作者可以控制的 URL 范围。这通常是一个相对 URL。它相对于应用程序的基本 URL。默认情况下,服务工作者注册的 scope 值设置为服务工作者脚本所在目录(通过解析相对于 scriptURL./)。有关其工作原理的更多信息,请参阅示例部分。

type

一个字符串,指定要创建的工作者类型。有效值为

'classic'

加载的服务工作者位于标准脚本中。这是默认值。

'module'

加载的服务工作者位于ES 模块中,并且 import 语句在工作者上下文中可用。有关 ES 模块兼容性信息,请参阅ServiceWorker 接口的浏览器兼容性数据表

updateViaCache

一个字符串,指示在更新期间如何使用 HTTP 缓存来获取服务工作者脚本资源。注意:这仅指服务工作者脚本及其导入,而不指这些脚本获取的其他资源。

'all'

HTTP 缓存将查询主脚本和所有导入的脚本。如果在 HTTP 缓存中找不到新的条目,则从网络获取脚本。

'imports'

HTTP 缓存将查询导入,但主脚本将始终从网络更新。如果在 HTTP 缓存中找不到导入的新条目,则从网络获取它们。

'none'

HTTP 缓存不会用于主脚本或其导入。所有服务工作者脚本资源都将从网络更新。

返回值

一个Promise,它解析为一个ServiceWorkerRegistration对象。

示例

此处描述的示例应结合起来,以便更好地理解服务工作者作用域如何应用于页面。

以下示例使用 scope 的默认值(通过省略它)。假设服务工作者代码位于 example.com/sw.js,注册代码位于 example.com/index.html。服务工作者代码将控制 example.com/index.html 以及其下的页面,例如 example.com/product/description.html

js
if ("serviceWorker" in navigator) {
  // Register a service worker hosted at the root of the
  // site using the default scope.
  navigator.serviceWorker.register("./sw.js").then(
    (registration) => {
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      console.error(`Service worker registration failed: ${error}`);
    },
  );
} else {
  console.error("Service workers are not supported.");
}

以下代码(所有代码都在同一位置)将应用于与上述示例完全相同的页面。或者,如果服务工作者代码位于 example.com/product/sw.js,注册代码位于 example.com/product/description.html。那么服务工作者将仅应用于 example.com/product 下的资源。请记住,作用域(如果包含)使用页面的位置作为其基础。

js
if ("serviceWorker" in navigator) {
  // declaring scope manually
  navigator.serviceWorker.register("./sw.js", { scope: "./" }).then(
    (registration) => {
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      console.error(`Service worker registration failed: ${error}`);
    },
  );
} else {
  console.error("Service workers are not supported.");
}

围绕作用域的含义和使用存在频繁的混淆。服务工作者无法拥有比其自身位置更广泛的作用域,除非服务器在服务工作者脚本上的Service-Worker-Allowed标头中指定了更广泛的最大作用域。因此,当您需要比默认值更窄的作用域时,应使用 scope 选项。

以下代码(如果包含在网站根目录的 example.com/index.html 中)将仅应用于 example.com/product 下的资源。

js
if ("serviceWorker" in navigator) {
  // declaring scope manually
  navigator.serviceWorker.register("./sw.js", { scope: "/product/" }).then(
    (registration) => {
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      console.error(`Service worker registration failed: ${error}`);
    },
  );
} else {
  console.error("Service workers are not supported.");
}

如上所述,服务器可以通过在服务工作者脚本上设置 Service-Worker-Allowed 标头来更改默认最大作用域。在这种情况下,scope 选项应指定的作用域应比标头值窄,但可能比服务工作者位置大。

以下代码(如果包含在 example.com/product/index.html 中)将应用于 example.com 下的所有资源,如果服务器在提供 sw.js 时将 Service-Worker-Allowed 标头设置为 /https://example.com/。如果服务器未设置标头,则服务工作者注册将失败,因为请求的 scope 太广。

js
if ("serviceWorker" in navigator) {
  // Declaring a broadened scope
  navigator.serviceWorker.register("./sw.js", { scope: "/" }).then(
    (registration) => {
      // The registration succeeded because the Service-Worker-Allowed header
      // had set a broadened maximum scope for the service worker script
      console.log("Service worker registration succeeded:", registration);
    },
    (error) => {
      // This happens if the Service-Worker-Allowed header doesn't broaden the scope
      console.error(`Service worker registration failed: ${error}`);
    },
  );
} else {
  console.error("Service workers are not supported.");
}

规范

规范
Service Workers
# navigator-service-worker-register

浏览器兼容性

BCD 表格仅在启用 JavaScript 的浏览器中加载。

另请参阅