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 |
瀏覽器相容性
載入中…