ServiceWorkerContainer: register() 方法
注意:此功能在 Web Workers 中可用。
ServiceWorkerContainer 接口的 register() 方法用于为给定范围创建或更新一个 ServiceWorkerRegistration。如果成功,该注册会将提供的脚本 URL 与一个范围相关联,该范围随后用于将文档匹配到特定的 service worker。
每个唯一的范围只创建一个注册。如果为已存在的范围调用 register(),则该注册将使用 scriptURL 或 options 的任何更改进行更新。如果没有更改,则返回现有的注册。使用相同的范围和 scriptURL 调用 register() 不会重新启动安装过程,因此通常可以从受控页面无条件调用此方法。但是,它会发送对 service worker 脚本的网络请求,这可能会增加服务器的负载。如果这令人担忧,您可以使用 ServiceWorkerContainer.getRegistration() 检查是否已存在注册。
一个文档可能属于具有不同 service worker 和选项的多个注册的范围。浏览器会将该文档与具有最具体范围的匹配注册相关联。这确保了每个文档只运行一个 service worker。
注意: 通常最好不要定义具有重叠范围的注册。
语法
register(scriptURL)
register(scriptURL, options)
参数
scriptURL-
service worker 脚本的 URL。注册的 service worker 文件需要具有有效的 JavaScript MIME 类型。
options可选-
包含注册选项的对象。目前可用的选项有:
scope-
一个字符串,表示定义 service worker 注册范围的 URL;也就是说,service worker 可以控制的 URL 的范围。
这通常被指定为相对于站点基 URL 的 URL(例如,
/some/path/),这样无论从哪个页面调用注册代码,解析后的范围都是相同的。service worker 注册的默认scope是 service worker 脚本所在目录(相对于scriptURL解析./)。范围应该用于指定与 service worker 相同目录或更深层目录下的文档。如果您需要更广泛的范围,可以通过 HTTP
Service-Worker-Allowed标头来实现。有关扩展 service worker 默认范围的信息,请参阅 示例 部分。 type-
一个字符串,指定要创建的工作程序的类型。有效值为:
'classic'-
加载的 service worker 是标准脚本。这是默认值。
'module'-
加载的 service worker 是 ES 模块,并且 import 语句在 worker 上下文中可用。有关 ES 模块兼容性信息,请参阅
ServiceWorker接口的浏览器兼容性数据表。
updateViaCache-
一个字符串,指示在更新期间如何使用 HTTP 缓存来处理 service worker 脚本资源。注意:这仅指 service worker 脚本及其导入,而不指这些脚本获取的其他资源。
返回值
一个 Promise,它解析为一个 ServiceWorkerRegistration 对象。
异常
TypeError-
scriptURL或scope URL发生错误。如果 URL 无法解析为有效 URL,或使用了非http:或https的协议,则可能发生此情况。如果scriptURL不是TrustedScriptURL,并且这是站点 Trusted Types Policy 的要求,也可能发生此情况。如果
scriptURL或scope URL路径包含不区分大小写的 ASCII "%2f"(*)或 "%5c"(=),则也会引发该异常。 SecurityErrorDOMException-
scriptURL不是一个潜在可信的源,例如localhost或httpsURL。scriptURL和范围与注册页面不是同源的。
示例
应将下面的示例结合起来阅读,以了解 service worker 范围如何应用于页面。
使用默认范围注册 service worker
以下示例通过省略 scope 的值来使用其默认值,将其设置为与脚本 URL 相同的位置。
假设 service worker 代码位于 example.com/sw.js,注册代码位于 example.com/index.html。service worker 代码将控制 example.com/index.html 以及其下的页面,例如 example.com/product/description.html。
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.");
}
请注意,我们已相对于站点根目录而非当前页面注册了 scriptURL。这允许从任何页面使用相同的注册代码。
使用显式默认范围注册 service worker
下面的代码几乎相同,只是我们使用 { scope: "/" } 显式指定了范围。我们将范围指定为站点相对路径,以便可以从站点的任何位置使用相同的注册代码。
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.");
}
此范围与默认范围相同,因此注册适用于与上一个示例完全相同的页面。请注意,如果我们在上一个示例之后运行此代码,浏览器应该会识别出我们正在更新现有注册而不是新的注册。
使用页面相对 URL 注册 service worker
没有什么阻止您使用页面相对 URL,只是这使得移动页面变得更加困难,而且这样做很容易意外创建不需要的注册。
在此示例中,service worker 代码位于 example.com/product/sw.js,注册代码位于 example.com/product/description.html。我们为 scriptURL 和 scope 使用了相对于当前目录的 URL,当前目录是调用 register() 的页面的基础 URL(example.com/product/)。service worker 适用于 example.com/product/ 下的资源。
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 扩展 service worker 范围
除非服务器在 service worker 脚本上使用 Service-Worker-Allowed 标头指定了更广泛的最大范围,否则 service worker 的范围不能比其自身位置更广。当您需要比默认值更窄的范围时,请使用 scope 选项。
以下代码如果包含在站点根目录的 example.com/index.html 中,则仅适用于 example.com/product 下的资源。
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.");
}
如上所述,服务器可以通过在服务 sw.js 时设置 Service-Worker-Allowed 标头来更改默认范围。这允许 scope 选项设置在 service worker 位置定义的路径之外。
如果以下代码包含在 example.com/product/index.html 中,并且服务器在服务 sw.js 时将 Service-Worker-Allowed 标头设置为 / 或 https://example.com/,则它将适用于 example.com 下的所有资源。如果服务器未设置该标头,则请求的 scope 过宽,导致 service worker 注册失败。
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 |
浏览器兼容性
加载中…