サービスワーカー

W3C 候補勧告草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2025/CRD-service-workers-20250306/
最新公開バージョン:
https://www.w3.org/TR/service-workers/
編集者草案:
https://w3c.github.io/ServiceWorker/
履歴:
https://www.w3.org/standards/history/service-workers/
実装報告:
https://wpt.fyi/service-workers
フィードバック:
GitHub
仕様内インライン
編集者:
(Microsoft)
(Google)
以前の編集者:
(Google)
(Google)
(Microsoft、2018年4月までSamsungを代表)
(Google)
テスト:
web-platform-tests service-workers/ (継続中の作業)

概要

この仕様の核となるのは、イベントを受け取るために起動されるワーカーです。これは、他の宛先が不適切である場合や、他に宛先が存在しない場合に使用できるイベントの宛先を提供します。

例えば、ページの取得方法を開発者が決定できるようにするためには、そのオリジンの他の実行コンテキストが存在する前にイベントを配送する必要があります。また、プッシュメッセージへの対応や永続的なダウンロードの完了時には、元々関心を登録したコンテキストがすでに存在しない場合があります。これらの場合、サービスワーカーが理想的なイベントの宛先となります。

この仕様はさらに、fetchイベントや、HTTPキャッシュの設計に似たリクエストとレスポンスのストアも提供し、オフライン対応のWebアプリケーションの構築を容易にします。

この文書の位置付け

このセクションは、公開時点での文書の位置付けを説明します。現在のW3C公開文書とこの技術仕様の最新改訂は、W3C技術仕様インデックス(https://www.w3.org/TR/)でご覧いただけます。

本文書は、Web Applications Working Groupにより、 勧告トラックを用いて候補勧告草案として公開されました。

本仕様へのフィードバックやコメントは歓迎します。バグを報告したり、public-webapps@w3.org購読アーカイブ)に[service-workers]と件名の先頭に記載してコメントを送信してください。

候補勧告としての公開は、W3Cおよびその会員による支持を意味するものではありません。候補勧告草案は、作業グループが次回の候補勧告スナップショットに含める予定の、以前の候補勧告からの変更点を統合しています。

本文書は草案であり、随時更新・置換・廃止される可能性があります。他の文書を引用する場合は、作業途中のものとして扱ってください。

本文書は、W3C特許ポリシーの下で運営されるグループによって作成されました。 W3Cは、グループの成果物に関連した公開特許開示リストを管理しています。そのページには特許の開示方法も記載されています。特許について実際に知識を有し、その特許が必須クレームを含むと考える場合、W3C特許ポリシー第6節に従って情報を開示しなければなりません。

この文書は、2023年11月3日W3Cプロセス文書に準拠しています。

1. 動機

このセクションは規範的ではありません。

Webアプリケーションは従来、ネットワークが到達可能であることを前提としています。この前提はプラットフォーム全体に浸透しています。HTML文書はHTTP経由で読み込まれ、従来はすべてのサブリソースも後続のHTTPリクエストで取得されます。このため、Webコンテンツは他の技術スタックと比べて不利な立場に置かれます。

サービスワーカーは、Web Workerコンテキストを提供することで、このバランスを是正するために設計されました。これは、ナビゲーションが発生する際にランタイムによって起動できるイベント駆動型ワーカーです。ワーカーは、オリジンとパス(またはパターン)に対して登録されるため、その場所へのナビゲーションが発生したときに参照されます。ネットワークリクエストに対応するイベントがワーカーに配送され、ワーカーが生成するレスポンスはデフォルトのネットワークスタックの動作を上書きする場合があります。これにより、サービスワーカーは概念的にネットワークとドキュメントレンダラーの間に位置し、オフライン時でもドキュメントにコンテンツを提供することができます。

以前のオフライン問題の解決策に慣れたWeb開発者からは、それらの解決策には柔軟性が欠如していると指摘されています。その結果、サービスワーカーは非常に手続き型となり、柔軟性を最大限に高める代わりに開発者により多くの複雑さをもたらします。この複雑さの一部は、サービスワーカーを単一スレッド実行モデルでも応答性を保つ必要から生じています。そのため、サービスワーカーが公開するAPIはほぼすべて非同期であり、他のJavaScriptコンテキストにも見られるパターンですが、ここではドキュメントやリソースの読み込みをブロックしない必要性から強調されています。

HTML5 Application Cacheを利用している開発者も、設計上のいくつかの属性が報告されているように回復不可能なエラーを引き起こす要因となっています。サービスワーカーの主要な設計原則は、エラーが常に回復可能であるべきだということです。サービスワーカーのアップデートプロセスの多くの詳細は、これらの危険を避けるように設計されています。

サービスワーカーは、ドキュメントではなくイベントとの関係によって開始・存続します。この設計は、共有ワーカーChromeのバックグラウンドページに関する開発者やベンダーの経験を多く取り入れています。これらのシステムから得られた重要な教訓は、リソースの節約と背景コンテキストの喪失・再起動を開発者の意識の中心に置くために、バックグラウンド処理コンテキストの実行時間を制限する必要性です。その結果、サービスワーカーは、バックグラウンドページの後継であるChromeイベントページに非常に似ています。サービスワーカーは、ドキュメントが紐付いていなくてもユーザーエージェントによって起動され、ほぼいつでもユーザーエージェントによって終了させることができます。概念的には、サービスワーカーは、ドキュメントからのメッセージを処理することなく起動・イベント処理・終了ができる共有ワーカーと考えることができます。サービスワーカーは、1秒間に何度も起動・終了される可能性があることを開発者は意識しておくべきです。

サービスワーカーは、汎用的・イベント駆動・時間制限付きのスクリプトコンテキストであり、オリジンで実行されます。これらの特性により、特定のドキュメントのコンテキストを超えて存続するランタイムサービス(例:プッシュ通知の処理、バックグラウンドデータ同期、他のオリジンからのリソース要求への対応、計算コストの高いデータ(例:位置情報やジャイロスコープ)への一元的更新の受信)に自然なエンドポイントとなります。

2. モデル

2.1. サービスワーカー

サービスワーカーは、Web Workerの一種です。サービスワーカーは、登録元のサービスワークラクライアントオリジンで実行されます。

サービスワーカーは、"parsed"、"installing"、"installed"、"activating"、"activated"、"redundant"のいずれかの状態を持ちます。初期状態は"parsed"です。

サービスワーカーは、スクリプトURLURL)を持ちます。

サービスワーカーは、"classic"または"module"のいずれかのを持ちます。特に明記されていない限り、"classic"です。

サービスワーカーは、含有サービスワーカー登録サービスワーカー登録)を持ち、自身を含みます。

サービスワーカーは、グローバルオブジェクトServiceWorkerGlobalScopeオブジェクトまたはnull)を持ちます。

サービスワーカーは、スクリプトリソーススクリプト)を持ち、自身のスクリプトリソースを表します。初期値はnullです。

スクリプトリソースは、評価済みフラグを持ちます。初期状態は未設定です。

スクリプトリソースは、ポリシーコンテナポリシーコンテナ)を持ちます。初期値は新規ポリシーコンテナです。

サービスワーカーは、スクリプトリソースマップ順序付きマップ)を持ち、キーはURL、値はレスポンスです。

サービスワーカーは、使用済みスクリプト集合集合)を持ち、要素URLです。初期値は新規集合です。

注: 使用済みスクリプト集合は、新しいワーカーのインストール後に未使用リソースをマップから削除するためだけに利用され、アップデートチェック時に古いワーカーのマップを元に構築されます。

サービスワーカーは、skip waitingフラグを持ち、特に明記されていない限り未設定です。

サービスワーカーは、クラシックスクリプトインポート済みフラグを持ち、初期状態は未設定です。

サービスワーカーは、処理対象イベントタイプ集合集合)を持ち、要素イベントリスナーのイベントタイプです。初期値は新規集合です。

サービスワーカーは、拡張イベント集合集合)を持ち、要素ExtendableEventです。初期値は新規集合です。

サービスワーカーは、nullまたはCompletionとなる開始状態を持ちます。初期値はnullです。

サービスワーカーは、全fetchリスナー空フラグを持ちます。初期状態は未設定です。

サービスワーカーは、ルーター規則リストリストRouterRuleのリスト)を持ち、初期値は空リストです。

サービスワーカーは、実行中であると言い、これはイベントループが稼働している状態です。

サービスワーカーは、[[service worker queue]]並列キュー)を持ちます。

2.1.1. ライフタイム

サービスワーカーのライフタイムはイベントの実行時間に紐付いており、サービスワークラクライアントServiceWorkerオブジェクトを保持しているかどうかには依存しません。

ユーザーエージェントは、以下の場合いつでもサービスワーカーを終了することがあります

  • 処理するイベントが存在しない場合。

  • 異常な動作(例:イベント処理中の無限ループや課せられた時間制限(存在する場合)を超えるタスク)を検出した場合。

2.1.2. イベント

Service Workers仕様は、サービスワーカーイベント(すべてイベント)を定義しており、以下を含みます(一覧参照):

2.2. サービスワーカーのタイミング

サービスワーカーは、後に navigation timing API で公開される特定の時点を記録します。

サービスワーカータイミング情報は、構造体です。次の項目を持ちます:

開始時刻

DOMHighResTimeStamp、初期値は0。

fetchイベント配送時刻

DOMHighResTimeStamp、初期値は0。

2.3. サービスワーカーの登録

サービスワーカー登録は、スコープURLストレージキー、およびサービスワーカーのセット、インストール中ワーカー待機ワーカーアクティブワーカーからなるタプルです。ユーザーエージェントは、スコープURLが異なる限り、1つのオリジンで複数のサービスワーカー登録を有効にすることができます。ユーザーエージェント内ですでに存在するスコープURLと同一のサービスワーカー登録が新たに作成された場合、既存のサービスワーカー登録は置き換えられます。

サービスワーカー登録には、関連付けられたストレージキーストレージキー)があります。

サービスワーカー登録には、関連付けられたスコープURLURL)があります。

サービスワーカー登録には、関連付けられたインストール中ワーカーサービスワーカーまたはnull)があり、その状態は"installing"です。初期値はnullです。

サービスワーカー登録には、関連付けられた待機ワーカーサービスワーカーまたはnull)があり、その状態は"installed"です。初期値はnullです。

サービスワーカー登録には、関連付けられたアクティブワーカーサービスワーカーまたはnull)があり、その状態は"activating"または"activated"です。初期値はnullです。

サービスワーカー登録には、関連付けられた最終更新確認時刻があります。初期値はnullです。

サービスワーカー登録は、登録の最終更新確認時刻がnullでなく、現在時刻から登録の最終更新確認時刻を引いた秒数が86400より大きい場合、古くなっているとされます。

サービスワーカー登録には、関連付けられたキャッシュ経由での更新モードがあり、"imports"、"all"、または"none"のいずれかです。初期値は"imports"です。

サービスワーカー登録には、1つ以上のタスクキューがあり、タスクアクティブワーカーイベントループに対応するタスクキューからバックアップします。(このバックアップ操作のターゲットタスクソースは、fetch処理タスクソースおよび機能イベント処理タスクソースです。)ユーザーエージェントは、アクティブワーカー終了されたとき、アクティブワーカータスクサービスワーカー登録タスクキューにダンプし、アクティブワーカーが再起動されたときにそれらのタスクを再度キューイングします。イベントループが所有するタスクキューとは異なり、サービスワーカー登録タスクキュー自体は、いかなるイベントループによっても処理されません。

サービスワーカー登録には、関連付けられたNavigationPreloadManagerオブジェクトがあります。

サービスワーカー登録には、関連付けられたナビゲーションプリロード有効フラグがあります。初期状態は未設定です。

サービスワーカー登録には、関連付けられたナビゲーションプリロードヘッダー値バイト列)があります。初期値はtrueです。

サービスワーカー登録は、登録マップ[このストレージキーシリアライズされたスコープURL]がこのサービスワーカー登録でない場合、登録解除済みとされます。

2.3.1. ライフタイム

ユーザーエージェントは、明示的に未登録されない限り、登録済みサービスワーカー登録のリストを永続的に保持しなければなりません。ユーザーエージェントは、サービスワーカー登録の(ストレージキー, 直列化された スコープURL)のタプルと、それに対応するサービスワーカー登録を格納するregistration mapを持ちます。サービスワーカー登録のライフタイムは、対応するサービスワークラクライアントのライフタイム内でそれを表すServiceWorkerRegistrationオブジェクトのライフタイムよりも長いです。

2.4. サービスワークラクライアント

サービスワークラクライアントは、環境です。

サービスワークラクライアントは、破棄フラグを持ちます。初期状態は未設定です。

サービスワークラクライアントは、以下の環境破棄手順を持ちます:

  1. client破棄フラグを設定する。

注: 実装は、破棄フラグが設定されたクライアントを破棄することができます。

サービスワークラクライアントは、originとして定義されるアルゴリズムを持ち、サービスワークラクライアント環境設定オブジェクトの場合は、そのoriginを返し、それ以外の場合はサービスワークラクライアント作成URLoriginを返します。

ウィンドウクライアントは、サービスワークラクライアントであり、そのグローバルオブジェクトWindowオブジェクトです。

専用ワークラクライアントは、サービスワークラクライアントであり、そのグローバルオブジェクトDedicatedWorkerGlobalScopeオブジェクトです。

共有ワークラクライアントは、サービスワークラクライアントであり、そのグローバルオブジェクトSharedWorkerGlobalScopeオブジェクトです。

ワークラクライアントは、専用ワークラクライアントまたは共有ワークラクライアントのいずれかです。

2.5. 制御と利用

サービスワークラクライアントは、自身の読み込みやサブリソースのためのアクティブサービスワーカーを持ちます。サービスワークラクライアントが非nullのアクティブサービスワーカーを持つ場合、そのクライアントはそのアクティブサービスワーカーによって制御されていると言います。また、サービスワークラクライアントサービスワーカー利用されている場合、そのクライアントは含有サービスワーカー登録を利用していると言います。 サービスワークラクライアントアクティブサービスワーカーは以下のサブセクションで説明する通りに決定されます。

このセクションの残り部分は規範的ではありません。

このセクションの挙動はまだ完全には規定されておらず、HTML標準で規定される予定です。作業はissueおよびpull requestで追跡されています。

2.5.1. ウィンドウクライアントの場合

ウィンドウクライアントは、作成されるとき、ブラウジングコンテキスト作成されたときや、ナビゲーション時に作成されます。

ウィンドウクライアント作成され、ブラウジングコンテキスト作成過程にある場合:

そのブラウジングコンテキストの初期アクティブドキュメントorigin不透明なoriginの場合、ウィンドウクライアントアクティブサービスワーカーはnullになります。 それ以外の場合は、作成元ドキュメントサービスワークラクライアントアクティブサービスワーカーに設定されます。

ウィンドウクライアント作成され、ブラウジングコンテキストナビゲーション過程にある場合:

fetchHTTP fetchを経由する場合、ウィンドウクライアントアクティブサービスワーカーサービスワーカー登録一致の結果になります。 それ以外の場合、新たに作成されたドキュメントorigin不透明なoriginであるか、作成元ドキュメントorigin同一でない場合、ウィンドウクライアントアクティブサービスワーカーはnullになります。 それ以外の場合は、作成元ドキュメントサービスワークラクライアントアクティブサービスワーカーに設定されます。

注: 初回置換ナビゲーションの場合、ウィンドウクライアント作成時にブラウジングコンテキスト作成されたものが再利用されますが、アクティブサービスワーカーの決定は上記と同じ動作に従います。

注: sandboxediframeでsandbox属性にallow-same-originおよびallow-scriptsが指定されていない場合は、アクティブサービスワーカー値がnullになります。これはorigin不透明なoriginとなるためです。

2.5.2. ワークラクライアントの場合

ワークラクライアントは、ユーザーエージェントが作成し、ワーカーを実行したときに作成されます。

ワークラクライアントが作成されたとき:

fetchHTTP fetchを経由する場合、ワークラクライアントアクティブサービスワーカーサービスワーカー登録一致の結果になります。 それ以外の場合、ワークラクライアントorigin不透明なoriginである場合や、リクエストURLblob URLで、そのワークラクライアントorigin同一でない場合、最後の項目ワークラクライアントグローバルオブジェクトowner setのoriginと一致しない場合、ワークラクライアントアクティブサービスワーカーはnullになります。 それ以外の場合は、最後の項目ワークラクライアントグローバルオブジェクトowner set環境設定オブジェクトアクティブサービスワーカーに設定されます。

注: ウィンドウクライアントワークラクライアントdata: URLを持つ場合、アクティブサービスワーカー値はnullとなります。これはoriginが不透明なoriginとなるためです。ウィンドウクライアントワークラクライアントblob URLを持つ場合は、作成元ドキュメントや所有者のアクティブサービスワーカーを継承できますが、リクエストoriginが、作成元ドキュメントや所有者のorigin同一でない場合、アクティブサービスワーカーはnullになります。

2.6. タスクソース

以下の追加のタスクソースサービスワーカーで利用されます。

fetch処理タスクソース

このタスクソースは、fetchイベントをサービスワーカーへ配送するために利用されます。

機能イベント処理タスクソース

このタスクソースは、他の機能イベント(例: pushイベント)をサービスワーカーへ配送する機能で利用されます。

注: ユーザーエージェントは、特定の機能イベントでヘッドオブラインブロッキング現象を避けるため、各機能イベントタイプごとに個別のタスクソースを利用する場合があります。

2.7. ユーザーエージェントのシャットダウン

ユーザーエージェントは、保存されたサービスワーカー登録の状態を再起動時にも維持しなければなりません。ただし、以下のルールに従います:

これを実現するため、ユーザーエージェントは終了時にユーザーエージェントのシャットダウン処理を呼び出す必要があります

3. クライアントコンテキスト

サービスワーカーによるブートストラップ:
// スコープはデフォルトでスクリプトが存在するパスになります
// この例では "/" です
navigator.serviceWorker.register("/serviceworker.js").then(registration => {
  console.log("success!");
  if (registration.installing) {
    registration.installing.postMessage("インストール中のページからこんにちは");
  }
}, err => {
  console.error("ワーカーのインストールに失敗しました!", err);
});

3.1. ServiceWorker

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorker : EventTarget {
  readonly attribute USVString scriptURL;
  readonly attribute ServiceWorkerState state;
  undefined postMessage(any message, sequence<object> transfer);
  undefined postMessage(any message, optional StructuredSerializeOptions options = {});

  // event
  attribute EventHandler onstatechange;
};
ServiceWorker includes AbstractWorker;

enum ServiceWorkerState {
  "parsed",
  "installing",
  "installed",
  "activating",
  "activated",
  "redundant"
};

ServiceWorker オブジェクトは サービスワーカーを表します。各 ServiceWorker オブジェクトは サービスワーカー に関連付けられます。複数のドキュメントやワーカーで ServiceWorker インターフェースを実装する個別のオブジェクトが、同じ サービスワーカー に同時に関連付けられることができます。

ServiceWorker オブジェクトは ServiceWorkerState オブジェクトを持ち、これは サービスワーカーstate に関連付けられています。

3.1.1. ServiceWorker インスタンスの取得

環境設定オブジェクトサービスワーカーオブジェクトマップマップ)を持ち、キーサービスワーカーServiceWorker オブジェクトです。

service worker オブジェクトの取得serviceWorkerサービスワーカー)を environment環境設定オブジェクト)で表す場合、以下の手順を実行する:
  1. objectMapenvironmentサービスワーカーオブジェクトマップとする。

  2. objectMap[serviceWorker] が 存在しない場合:

    1. serviceWorkerObjenvironmentRealm で新規作成した ServiceWorker とし、serviceWorker に関連付ける。

    2. serviceWorkerObjstateserviceWorkerstate に設定する。

    3. objectMap[serviceWorker] に serviceWorkerObj を設定する。

  3. objectMap[serviceWorker] を返す。

3.1.2. scriptURL

scriptURL ゲッター手順は、サービスワーカー直列化された script url を返す。

例:https://example.com/app.htmlへのナビゲーションで作成されたドキュメントが、次の登録呼び出しによって(事前に実行済み)マッチされた場合:
// ページ https://example.com/app.html 上のスクリプト
navigator.serviceWorker.register("/service_worker.js");

navigator.serviceWorker.controller.scriptURL の値は "https://example.com/service_worker.js" となります。

3.1.3. state

state 属性は、(ServiceWorkerState列挙)で最後に設定された値を返さなければなりません

3.1.4. postMessage(message, transfer)

postMessage(message, transfer) メソッド手順:

  1. options を «[ "transfer" → transfer ]» とする。

  2. messageoptions を引数に postMessage(message, options) を呼び出す。

3.1.5. postMessage(message, options)

postMessage(message, options) メソッド手順:

  1. serviceWorkerサービスワーカーthisで表される)とする。

  2. incumbentSettings現職設定オブジェクトとする。

  3. incumbentGlobalincumbentSettingsグローバルオブジェクトとする。

  4. serializeWithTransferResultStructuredSerializeWithTransfer(message, options["transfer"]) の結果とする。例外は再スローする。

  5. "message" と serviceWorkerイベントスキップ判定アルゴリズムの結果が true なら return。

  6. 以下のサブステップを 並列で実行:

    1. serviceWorkerサービスワーカーの実行アルゴリズムの結果が failure なら return。

    2. DOM操作タスクソースで以下を実行:

      1. incumbentGlobal の型に応じて source を決定:

        ServiceWorkerGlobalScope
        incumbentGlobalservice workerserviceWorker関連設定オブジェクトで表すサービスワーカーオブジェクト取得の結果
        Window
        incumbentGlobal関連設定オブジェクトを表す新しい WindowClient オブジェクト
        その他
        incumbentGlobal の関連ワーカーを表す新しい Client オブジェクト
      2. originincumbentSettingsoriginASCII直列化結果とする。

      3. destinationserviceWorker に関連付けられた ServiceWorkerGlobalScope オブジェクトとする。

      4. deserializeRecordStructuredDeserializeWithTransfer(serializeWithTransferResult, destinationRealm) とする。

        例外が発生した場合は、originを初期化した messageerror イベントを ExtendableMessageEvent を使い作成し、source を初期化する。

      5. それ以外:

        1. messageClonedeserializeRecord.[[Deserialized]] とする。

        2. newPortsdeserializeRecord.[[TransferredValues]] 内のすべての MessagePort オブジェクトから作成した新しい frozen array(順序維持)とする。

        3. eoriginsourcemessageClonenewPortsを初期化した message イベントとして ExtendableMessageEvent を使い作成する。

      6. Dispatch edestination で実行。

      7. サービスワーカー拡張イベントセットの更新serviceWorkere で呼び出す。

3.1.6. イベントハンドラー

以下は イベントハンドラー(および対応する イベントハンドラーイベントタイプ)であり、すべての ServiceWorker インターフェース実装オブジェクトで イベントハンドラーIDL属性としてサポートしなければなりません

event handler event handler event type
onstatechange statechange

3.2. ServiceWorkerRegistration

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;
  [SameObject] readonly attribute NavigationPreloadManager navigationPreload;

  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;

  [NewObject] Promise<undefined> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

enum ServiceWorkerUpdateViaCache {
  "imports",
  "all",
  "none"
};

ServiceWorkerRegistrationは、サービスワーカー登録サービスワーカー登録)を持ちます。

3.2.1. ServiceWorkerRegistrationインスタンスの取得

環境設定オブジェクトは、サービスワーカー登録オブジェクトマップを持ちます。これは、マップであり、キーサービスワーカー登録ServiceWorkerRegistrationオブジェクトです。

サービスワーカー登録オブジェクトの取得registrationサービスワーカー登録)をenvironment環境設定オブジェクト)で表す場合、以下の手順を実行する:
  1. objectMapenvironmentサービスワーカー登録オブジェクトマップとする。

  2. objectMap[registration]が存在しない場合:

    1. registrationObjectenvironmentRealmで新規作成したServiceWorkerRegistrationとする。

    2. registrationObjectサービスワーカー登録registrationに設定する。

    3. registrationObjectinstalling属性をnullに設定する。

    4. registrationObjectwaiting属性をnullに設定する。

    5. registrationObjectactive属性をnullに設定する。

    6. registrationinstalling workerがnullでない場合、registrationObjectinstalling属性をregistrationinstalling workerenvironmentで表すサービスワーカーオブジェクト取得の結果に設定する。

    7. registrationwaiting workerがnullでない場合、registrationObjectwaiting属性をregistrationwaiting workerenvironmentで表すサービスワーカーオブジェクト取得の結果に設定する。

    8. registrationactive workerがnullでない場合、registrationObjectactive属性をregistrationactive workerenvironmentで表すサービスワーカーオブジェクト取得の結果に設定する。

    9. objectMap[registration]にregistrationObjectを設定する。

  3. objectMap[registration]を返す。

installing属性は、最後に設定された値を返さなければなりません

注: Realm内では、関連付けられたサービスワーカーごとに1つのServiceWorkerオブジェクトのみ存在します。

waiting属性は、最後に設定された値を返さなければなりません

注: Realm内では、関連付けられたサービスワーカーごとに1つのServiceWorkerオブジェクトのみ存在します。

active属性は、最後に設定された値を返さなければなりません

注: Realm内では、関連付けられたサービスワーカーごとに1つのServiceWorkerオブジェクトのみ存在します。

3.2.5. navigationPreload

navigationPreloadゲッター手順は、サービスワーカー登録NavigationPreloadManagerオブジェクトを返すこと。

3.2.6. scope

scopeゲッター手順は、サービスワーカー登録直列化されたscope urlを返すこと。

§ 3.1.2 scriptURLの例では、registration.scope(例えばnavigator.serviceWorker.ready.then(registration => console.log(registration.scope))で取得)は"https://example.com/"となります。

3.2.7. updateViaCache

updateViaCacheゲッター手順は、サービスワーカー登録update via cacheモードを返すこと。

3.2.8. update()

update()メソッド手順:

  1. registrationサービスワーカー登録とする。

  2. newestWorker最新ワーカー取得アルゴリズムでregistrationを引数に実行した結果にする。

  3. newestWorkerがnullの場合、失敗したpromise("InvalidStateError"DOMException)を返して中断。

  4. this関連グローバルオブジェクトglobalObjectServiceWorkerGlobalScopeオブジェクトであり、globalObjectの関連サービスワーカーのstateが"installing"の場合、失敗したpromise("InvalidStateError"DOMException)を返して中断。

  5. promisepromiseとする。

  6. jobジョブ作成アルゴリズムで、update、registrationstorage keyregistrationscope urlnewestWorkerscript urlpromisethis関連設定オブジェクトを引数に実行した結果にする。

  7. jobworker typenewestWorkertypeに設定する。

  8. ジョブスケジュールjobで呼び出す。

  9. promiseを返す。

注: unregister()メソッドはサービスワーカー登録を解除します。現在制御されているサービスワークラクライアントアクティブサービスワーカー含有サービスワーカー登録は、そのサービスワーカー登録を利用するすべてのサービスワークラクライアント(自身を含む)がアンロードされるまで有効です。つまり、unregister()メソッドは、以降のナビゲーションにのみ影響します。

unregister()メソッド手順:

  1. registrationサービスワーカー登録とする。

  2. promise新規promiseとする。

  3. jobジョブ作成アルゴリズムで、unregister、registrationstorage keyregistrationscope url、null、promisethis関連設定オブジェクトを引数に実行した結果にする。

  4. ジョブスケジュールjobで呼び出す。

  5. promiseを返す。

3.2.10. イベントハンドラー

以下はイベントハンドラー(および対応するイベントハンドラーイベントタイプ)であり、すべてのServiceWorkerRegistrationインターフェース実装オブジェクトでイベントハンドラーIDL属性としてサポートしなければなりません

event handler event handler event type
onupdatefound updatefound
partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

partial interface WorkerNavigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

serviceWorker ゲッターの手順は、ServiceWorkerContainer オブジェクトをthisに関連付けて返すことです。

3.4. ServiceWorkerContainer

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerContainer : EventTarget {
  readonly attribute ServiceWorker? controller;
  readonly attribute Promise<ServiceWorkerRegistration> ready;

  [NewObject] Promise<ServiceWorkerRegistration> register((TrustedScriptURL or USVString) scriptURL, optional RegistrationOptions options = {});

  [NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = "");
  [NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();

  undefined startMessages();


  // events
  attribute EventHandler oncontrollerchange;
  attribute EventHandler onmessage; // event.source of message events is ServiceWorker object
  attribute EventHandler onmessageerror;
};
dictionary RegistrationOptions {
  USVString scope;
  WorkerType type = "classic";
  ServiceWorkerUpdateViaCache updateViaCache = "imports";
};

ユーザーエージェントは、ServiceWorkerContainer オブジェクトをNavigator オブジェクトまたはWorkerNavigator オブジェクト作成時に生成し、それらのオブジェクトに関連付けなければなりません。

ServiceWorkerContainer は、サービスワーカー登録の登録・解除・更新の機能を提供し、サービスワーカー登録およびそれに関連するサービスワーカーの状態へのアクセスを提供します。

ServiceWorkerContainer は、関連するサービスワークラクライアントを持ちます。これは、サービスワークラクライアントであり、そのグローバルオブジェクトNavigator またはWorkerNavigator オブジェクトに関連付けられています。

ServiceWorkerContainer オブジェクトは、関連するready promisepromiseまたはnull)を持ちます。初期値はnullです。

ServiceWorkerContainer オブジェクトは、タスクソースとしてクライアントメッセージキュー(初期値は空)を持ちます。クライアントメッセージキューは有効・無効にでき、初期状態は無効です。ServiceWorkerContainer オブジェクトのクライアントメッセージキューが有効な場合、イベントループはそれをタスクソースの一つとして使用しなければなりませんServiceWorkerContainer オブジェクトの関連グローバルオブジェクトWindow オブジェクトの場合、すべてのタスクキューされる際、クライアントメッセージキューに関連付けられ、その関連設定オブジェクト関連ドキュメントに紐付けられます。

controller 属性の手順は以下の通り実行しなければなりません

  1. clientthisサービスワークラクライアントとする。

  2. clientアクティブサービスワーカー がnullの場合、nullを返す。

  3. clientアクティブサービスワーカーサービスワーカーオブジェクト取得で、this関連設定オブジェクトで表現した結果を返す。

注: navigator.serviceWorker.controller はリクエストが強制リフレッシュ(shift+refresh)の場合、nullを返します。

ready属性は以下の手順で実行しなければなりません

  1. thisready promiseがnullの場合、thisready promise新規promiseを設定する。

  2. readyPromisethisready promiseとする。

  3. readyPromiseがpendingの場合、以下のサブステップを並列で実行:

    1. clientthisサービスワークラクライアントとする。

    2. storage keyストレージキー取得でclientを引数に実行した結果とする。

    3. registrationサービスワーカー登録一致storage keyclient作成URLを引数に実行した結果とする。

    4. registrationがnullでなく、registrationactive workerがnullでない場合、DOM操作タスクソースreadyPromise関連設定オブジェクト責任イベントループにタスクをキューし、readyPromiseregistrationを表すサービスワーカー登録オブジェクト取得の結果で解決する。

  4. readyPromiseを返す。

注: 返されるready promiseはrejectされません。このアルゴリズムでresolveされない場合でも、該当するサービスワーカー登録が登録され、active workerが設定されると必ずresolveされます。(該当するActivateアルゴリズム参照)

注: register(scriptURL, options) メソッドは、指定されたscope urlサービスワーカー登録を新規作成または更新します。成功すると、提供されたscriptURLscope urlに関連付けられ、以後ナビゲーションマッチング(navigation matching)で使用されます。

register(scriptURL, options) メソッド手順:

  1. ppromiseとする。

  2. scriptURLTrustedScriptURLthis関連グローバルオブジェクトscriptURL、"ServiceWorkerContainer register"、"script"でGet Trusted Type compliant stringを呼び出した結果にする。

  3. clientthisサービスワークラクライアントとする。

  4. scriptURLURLパーサーthis関連設定オブジェクトAPI base URLで解析した結果にする。

  5. scopeURLをnullとする。

  6. options["scope"] が存在する場合、scopeURLURLパーサーoptions["scope"]をthis関連設定オブジェクトAPI base URLで解析した結果に設定する。

  7. Start RegisterscopeURLscriptURLpclientclient作成URLoptions["type"]、options["updateViaCache"]で呼び出す。

  8. pを返す。

getRegistration(clientURL) メソッド手順:

  1. clientthisサービスワークラクライアントとする。

  2. storage keyストレージキー取得でclientを引数に実行した結果とする。

  3. clientURLURLパーサーclientURLthis関連設定オブジェクトAPI base URLで解析した結果にする。

  4. clientURLが失敗の場合、promiseをTypeErrorでrejectして返す。

  5. clientURLfragmentをnullに設定する。

  6. clientURLoriginclientoriginでない場合、promiseをSecurityErrorのDOMExceptionでrejectして返す。

  7. promiseを新規promiseとする。

  8. 以下の手順を並列で実行:

    1. registrationサービスワーカー登録一致storage keyclientURLを引数に実行した結果とする。

    2. registrationがnullの場合、promiseをundefinedでresolveして手順終了。

    3. promiseをregistrationを表すサービスワーカー登録オブジェクト取得の結果でresolveする。

  9. promiseを返す。

getRegistrations() メソッド手順:

  1. clientthisサービスワークラクライアントとする。

  2. client storage keyストレージキー取得でclientを引数に実行した結果とする。

  3. promise新規promiseとする。

  4. 以下の手順を並列で実行:

    1. registrationsを新規リストとする。

    2. (storage key, scope) → registrationregistration mapから反復:

      1. storage keyclient storage key等しい場合、append registrationregistrationsへ追加。

    3. DOM操作タスクソースでpromiseの関連設定オブジェクト責任イベントループにタスクをキューして、以下を実行:

      1. registrationObjectsを新規リストとする。

      2. registrationregistrationsで反復:

        1. registrationObjregistrationを表すサービスワーカー登録オブジェクト取得の結果とする。

        2. append registrationObjregistrationObjectsに追加。

      3. promiseを新規frozen arrayregistrationObjectsをpromiseの関連Realmで解決する。

  5. promiseを返す。

startMessages()メソッドの手順は、thisクライアントメッセージキューが有効でなければ有効化すること。

3.4.7. イベントハンドラー

以下はイベントハンドラー(および対応するイベントハンドラーイベントタイプ)であり、すべてのServiceWorkerContainer インターフェース実装オブジェクトでイベントハンドラーIDL属性としてサポートしなければなりません

event handler event handler event type
oncontrollerchange controllerchange
onmessage message
onmessageerror messageerror

初めてonmessage セッター手順が実行された時、thisクライアントメッセージキューを有効化します。

3.5. イベント

以下のイベントは ServiceWorker オブジェクト上で配送されます:

イベント名 インターフェース 配送タイミング
statechange Event state 属性が ServiceWorker オブジェクトで変更されたとき。

以下のイベントは ServiceWorkerRegistration オブジェクト上で配送されます:

イベント名 インターフェース 配送タイミング
updatefound Event サービスワーカー登録installing worker が変更されたとき(Installアルゴリズムのステップ8参照)。

以下のイベントは ServiceWorkerContainer オブジェクト上で配送されます:

イベント名 インターフェース 配送タイミング
controllerchange Event サービスワークラクライアントアクティブサービスワーカーが変更されたとき(Activateアルゴリズムのステップ9.2参照。skip waitingフラグ付きのサービスワーカーactivationサービスワーカー登録サービスワークラクライアント利用されている間に発生させ、navigator.serviceWorker.controller は即座に active worker を、そのサービスワーカー制御するサービスワークラクライアントとして即座に反映します。)
message Event サービスワークラクライアントサービスワーカーからメッセージを受信したとき。postMessage(message, options)参照。
messageerror Event サービスワークラクライアントサービスワーカーからデシリアライズできないメッセージを受信したとき。postMessage(message, options)参照。
[SecureContext, Exposed=(Window,Worker)]
interface NavigationPreloadManager {
  Promise<undefined> enable();
  Promise<undefined> disable();
  Promise<undefined> setHeaderValue(ByteString value);
  Promise<NavigationPreloadState> getState();
};

dictionary NavigationPreloadState {
  boolean enabled = false;
  ByteString headerValue;
};

enable() メソッドの手順:

  1. promise新規promiseとする。

  2. 以下の手順を並列で実行:

    1. registrationthisの関連付けられたサービスワーカー登録とする。

    2. registrationactive workerがnullの場合、promiseを "InvalidStateError" DOMException でrejectし、この手順を中断。

    3. registrationnavigation preload enabled flagを設定する。

    4. promiseをundefinedでresolveする。

  3. promiseを返す。

disable() メソッドの手順:

  1. promise新規promiseとする。

  2. 以下の手順を並列で実行:

    1. registrationthisの関連付けられたサービスワーカー登録とする。

    2. registrationactive workerがnullの場合、promiseを "InvalidStateError" DOMException でrejectし、この手順を中断。

    3. registrationnavigation preload enabled flagを解除する。

    4. promiseをundefinedでresolveする。

  3. promiseを返す。

setHeaderValue(value) メソッドの手順:

  1. promise新規promiseとする。

  2. 以下の手順を並列で実行:

    1. registrationthisの関連付けられたサービスワーカー登録とする。

    2. registrationactive workerがnullの場合、promiseを "InvalidStateError" DOMException でrejectし、この手順を中断。

    3. registrationnavigation preload header valuevalueに設定する。

    4. promiseをundefinedでresolveする。

  3. promiseを返す。

getState() メソッドの手順:

  1. promise新規promiseとする。

  2. 以下の手順を並列で実行:

    1. registrationthisの関連付けられたサービスワーカー登録とする。

    2. stateを新規NavigationPreloadState辞書とする。

    3. registrationnavigation preload enabled flagが設定されている場合、state["enabled"]をtrueに設定する。

    4. state["headerValue"]をregistrationnavigation preload header valueに設定する。

    5. promiseをstateでresolveする。

  3. promiseを返す。

4. 実行コンテキスト

キャッシュされたリソースの提供:
// caching.js
self.addEventListener("install", event => {
  event.waitUntil(
    // リソースのキャッシュを開く。
    caches.open("shell-v1").then(cache => {
      // それらの取得処理を開始する。全てのリソースが保存された場合のみ成功。
      // 一つでも失敗すると、全体の操作は失敗となる。
      return cache.addAll([
        "/app.html",
        "/assets/v1/base.css",
        "/assets/v1/app.js",
        "/assets/v1/logo.png",
        "/assets/v1/intro_video.webm"
      ]);
    })
  );
});

self.addEventListener("fetch", event => {
  // Service Workerが正常にインストール・アクティベートされるまで、"fetch"イベントはディスパッチされない。

  // キャッシュ操作は全て非同期で行われるため、URL照合を含めPromiseを多用する。e.respondWith()もPromiseを受け付ける:
  event.respondWith(
    caches.match(e.request).then(response => {
      return response || fetch(e.request);
    }).catch(() => {
      return caches.match("/fallback.html");
    })
  );
});

4.1. ServiceWorkerGlobalScope

[Global=(Worker,ServiceWorker), Exposed=ServiceWorker, SecureContext]
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
  [SameObject] readonly attribute Clients clients;
  [SameObject] readonly attribute ServiceWorkerRegistration registration;
  [SameObject] readonly attribute ServiceWorker serviceWorker;

  [NewObject] Promise<undefined> skipWaiting();

  attribute EventHandler oninstall;
  attribute EventHandler onactivate;
  attribute EventHandler onfetch;

  attribute EventHandler onmessage;
  attribute EventHandler onmessageerror;
};

ServiceWorkerGlobalScope オブジェクトは、Service Worker のグローバルな実行コンテキストを表します。

ServiceWorkerGlobalScope オブジェクトは、関連付けられた service workerService Worker)を持ちます。

ServiceWorkerGlobalScope オブジェクトには、import scripts用キャッシュ強制バイパスフラグ が関連付けられています。初期状態では未設定です。

ServiceWorkerGlobalScope オブジェクトには、race response map が関連付けられています。これは 順序付きマップ であり、キーリクエスト で、 race response です。

race response は、構造体 であり、"race-network-and-fetch-handler" が実行された際のネットワークレスポンスを保持するために使われます。これは valueresponse、"pending" または null)を持ちます。

注: ServiceWorkerGlobalScope オブジェクトは、オリジンで実行される汎用的なイベント駆動型・時間制限付きスクリプトの実行コンテキストを提供します。 正常に 登録 されると、 Service Worker が起動し、 イベントとの関係によって存続・終了されます。 Service Workerクライアント との直接的な関係では存続しません。 Service Worker内で同期リクエストは開始しないでください。

4.1.1. clients

clients のgetterは、 Clients オブジェクト(this に関連するもの)を返します。

4.1.2. registration

registration のgetterは、 サービスワーカー登録オブジェクトの取得 の結果を返します。 これは thisservice worker含まれるService Worker登録該当設定オブジェクト内で表します。

4.1.3. serviceWorker

serviceWorker のgetterは、 Service Workerオブジェクトの取得 の結果を返します。 これは thisservice worker を、 該当設定オブジェクト内で表します。

4.1.4. skipWaiting()

注: skipWaiting() メソッドは、この Service Worker を、 登録waiting 状態から active 状態へと進めることができます。 Service Workerクライアント がその 登録利用している最中でも実行可能です。

skipWaiting() メソッドの手順:

  1. promise を新しい Promise とする。

  2. 以下のサブステップを 並行して実行する:

    1. service workerskip waitingフラグ を設定する。

    2. Try Activateservice worker含まれるService Worker登録 に対して呼び出す。

    3. promise を undefined で解決する。

  3. promise を返す。

4.1.5. イベントハンドラ

以下は、イベントハンドラ (対応する イベント型)であり、 ServiceWorkerGlobalScope インターフェースを実装する全てのオブジェクトで 必ず サポートされるべき イベントハンドラIDL属性 です:

イベントハンドラ イベント型
oninstall install
onactivate activate
onfetch fetch
onmessage message
onmessageerror messageerror

4.2. Client

[Exposed=ServiceWorker]
interface Client {
  readonly attribute USVString url;
  readonly attribute FrameType frameType;
  readonly attribute DOMString id;
  readonly attribute ClientType type;
  undefined postMessage(any message, sequence<object> transfer);
  undefined postMessage(any message, optional StructuredSerializeOptions options = {});
};

[Exposed=ServiceWorker]
interface WindowClient : Client {
  readonly attribute VisibilityState visibilityState;
  readonly attribute boolean focused;
  [SameObject] readonly attribute FrozenArray<USVString> ancestorOrigins;
  [NewObject] Promise<WindowClient> focus();
  [NewObject] Promise<WindowClient?> navigate(USVString url);
};

enum FrameType {
  "auxiliary",
  "top-level",
  "nested",
  "none"
};

Client オブジェクトには、関連付けられた service worker clientservice worker client)があります。

Client オブジェクトには、関連付けられた frame type(フレームタイプ)があり、"auxiliary"、"top-level"、"nested"、"none" のいずれかです。特に記載がなければ "none" となります。

WindowClient オブジェクトには、関連付けられた 閲覧コンテキスト(browsing context)があり、これはその service worker clientグローバルオブジェクト閲覧コンテキストです。

WindowClient オブジェクトには、関連付けられた 可視状態(visibility state)があり、これは visibilityState 属性値のいずれかです。

WindowClient オブジェクトには、関連付けられた フォーカス状態(focus state)があり、true または false(初期値は false)です。

WindowClient オブジェクトには、関連付けられた 先祖オリジン配列(ancestor origins array)があります。

4.2.1. url

url のgetter手順は、this に関連付けられた service worker client直列化された 作成URL を返します。

4.2.2. frameType

frameType のgetter手順は、thisframe type を返します。

4.2.3. id

id のgetter手順は、this に関連付けられた service worker clientid を返します。

4.2.4. type

type のgetter手順:

  1. clientthisservice worker client とする。

  2. clientenvironment settings object なら:

    1. clientwindow client なら "window" を返す。

    2. そうでなく、clientdedicated worker client なら "worker" を返す。

    3. さらにそうでなく、clientshared worker client なら "sharedworker" を返す。

  3. それ以外の場合:

    1. "window" を返す。

4.2.5. postMessage(message, transfer)

postMessage(message, transfer) メソッドの手順:

  1. options を «[ "transfer" → transfer ]» とする。

  2. postMessage(message, options)messageoptions を引数として呼び出す。

4.2.6. postMessage(message, options)

postMessage(message, options) メソッドの手順:

  1. contextObjectthis とする。

  2. sourceSettingscontextObject該当設定オブジェクト とする。

  3. serializeWithTransferResultStructuredSerializeWithTransfer(message, options["transfer"]) とする。例外は再スローする。

  4. 以下の手順を 並行して実行する:

    1. targetClient を null とする。

    2. service worker client client について:

      1. clientcontextObjectservice worker client であれば、targetClientclient を設定し、break する。

    3. targetClient が null なら return。

    4. destination を、関連する service worker clienttargetClient である ServiceWorkerContainer オブジェクトとする。

    5. destinationclient message queue に、次の手順を実行するタスクを追加する:

      1. originsourceSettingsorigin直列化とする。

      2. source を、service workerオブジェクトの取得の結果とし、これは contextObject該当グローバルオブジェクトservice workertargetClient で表す。

      3. deserializeRecordStructuredDeserializeWithTransfer(serializeWithTransferResult, destination該当Realm) とする。

        例外が発生した場合、それをキャッチし、messageerror イベントを destinationMessageEvent を使って発火し、origin 属性を origin で、source 属性を source で初期化し、その後これらの手順を中止する。

      4. messageClonedeserializeRecord.[[Deserialized]] とする。

      5. newPorts を、deserializeRecord.[[TransferredValues]] 内の全ての MessagePort オブジェクトからなる新しい frozen array とする(もしあれば)。

      6. message イベントを destinationMessageEvent を使って発火し、origin 属性を origin で、source 属性を source で、data 属性を messageClone で、ports 属性を newPorts で初期化する。

4.2.7. visibilityState

visibilityState のgetter手順は、this可視状態 を返します。

4.2.8. focused

focused のgetter手順は、thisフォーカス状態 を返します。

4.2.9. ancestorOrigins

ancestorOrigins のgetter手順は、this に関連付けられた 先祖オリジン配列 を返します。

4.2.10. focus()

focus() メソッド手順:

  1. この オリジンWindow が一つも 一時的なアクティベーション を持たない場合、"InvalidAccessError" DOMException で拒否された promise を返す。

  2. serviceWorkerEventLoop周囲のエージェントイベントループ とする。

  3. promise を新しい promise とする。

  4. タスクをキューに入れる。次の手順を this に関連付けられた service worker client責任イベントループ上で ユーザー操作タスクソース を使って実行する:

    1. フォーカス手順this閲覧コンテキスト に対して実行する。

    2. frameTypeGet Frame Typethis閲覧コンテキスト で実行した結果とする。

    3. visibilityStatethis閲覧コンテキストアクティブドキュメントvisibilityState 属性値とする。

    4. focusStatehas focus手順this閲覧コンテキストアクティブドキュメント に対して実行した結果とする。

    5. ancestorOriginsListthis閲覧コンテキストアクティブドキュメント該当グローバルオブジェクトLocation オブジェクトの 先祖オリジンリスト の関連リストとする。

    6. タスクをキューに入れる。次の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:

      1. windowClientCreate Window Clientthis に関連付けられた service worker clientframeTypevisibilityStatefocusStateancestorOriginsList を渡して実行した結果とする。

      2. windowClientフォーカス状態 が true なら、promisewindowClient で解決する。

      3. そうでなければ、promiseTypeError で拒否する。

  5. promise を返す。

4.2.11. navigate(url)

navigate(url) メソッド手順:

  1. urlパース した結果とし、this該当設定オブジェクトAPIベースURL を使う。

  2. url が失敗の場合、TypeError で拒否された promise を返す。

  3. urlabout:blank の場合、TypeError で拒否された promise を返す。

  4. this に関連付けられた service worker clientactive service workerthis該当グローバルオブジェクトservice worker でない場合、TypeError で拒否された promise を返す。

  5. serviceWorkerEventLoop現在のグローバルオブジェクトイベントループ とする。

  6. promise を新しい promise とする。

  7. タスクをキューに入れる。次の手順を this に関連付けられた service worker client責任イベントループ上で ユーザー操作タスクソース を使って実行する:

    1. browsingContextthis閲覧コンテキスト とする。

    2. browsingContext関連ドキュメント完全アクティブ でない場合、タスクをキューに入れるpromiseTypeErrorserviceWorkerEventLoop 上の DOM操作タスクソース で拒否し、これらの手順を中止する。

    3. HandleNavigate: ナビゲート browsingContexturl へ、browsingContext関連ドキュメント を使い、例外有効 を true とする。

    4. HandleNavigate ラベル付きのアルゴリズム手順が 例外 を投げた場合、タスクをキューに入れるpromise を例外で serviceWorkerEventLoop 上の DOM操作タスクソース で拒否し、これらの手順を中止する。

    5. frameTypeGet Frame TypebrowsingContext で実行した結果とする。

    6. visibilityStatebrowsingContextアクティブドキュメントvisibilityState 属性値とする。

    7. focusStatehas focus手順browsingContextアクティブドキュメント に対して実行した結果とする。

    8. ancestorOriginsListbrowsingContextアクティブドキュメント該当グローバルオブジェクトLocation オブジェクトの 先祖オリジンリスト の関連リストとする。

    9. タスクをキューに入れる。次の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:

      1. browsingContextWindow オブジェクトの environment settings object作成URLorigin同一 でない場合、service workerorigin と、promise を null で解決し、これらの手順を中止する。

      2. windowClientCreate Window Clientthisservice worker clientframeTypevisibilityStatefocusStateancestorOriginsList を渡して実行した結果とする。

      3. promisewindowClient で解決する。

  8. promise を返す。

4.3. Clients

[Exposed=ServiceWorker]
interface Clients {
  // 返されるオブジェクトは毎回新しいインスタンスとなる
  [NewObject] Promise<(Client or undefined)> get(DOMString id);
  [NewObject] Promise<FrozenArray<Client>> matchAll(optional ClientQueryOptions options = {});
  [NewObject] Promise<WindowClient?> openWindow(USVString url);
  [NewObject] Promise<undefined> claim();
};
dictionary ClientQueryOptions {
  boolean includeUncontrolled = false;
  ClientType type = "window";
};
enum ClientType {
  "window",
  "worker",
  "sharedworker",
  "all"
};

ユーザーエージェントは ServiceWorkerGlobalScope オブジェクトが作成されるとき、必ず Clients オブジェクトを作成し、そのオブジェクトに関連付けなければならない。

4.3.1. get(id)

get(id) メソッドの手順:

  1. promise を新しい promise とする。

  2. 以下のサブステップを 並行して実行する:

    1. service worker client client について、ストレージキーの取得 の結果が、関連する service worker含まれるService Worker登録ストレージキー と等しい場合:

      1. clientidid でない場合、continue

      2. client実行準備フラグ が設定されるか、client破棄フラグ が設定されるまで待つ。

      3. client実行準備フラグ が設定されたら、Get Client Promiseの解決clientpromise で呼び出し、これらの手順を中止する。

    2. promise を undefined で解決する。

  3. promise を返す。

4.3.2. matchAll(options)

matchAll(options) メソッドの手順:

  1. promise新しいpromise とする。

  2. 以下の手順を 並行して実行する:

    1. targetClients を新しい リスト とする。

    2. service worker client client について、ストレージキーの取得 の結果が、関連する service worker含まれるService Worker登録ストレージキー と等しい場合:

      1. client実行準備フラグ が未設定、または client破棄フラグ が設定されている場合、continue

      2. clientセキュアコンテキスト でない場合、continue

      3. options["includeUncontrolled"] が false であり、かつ clientactive service worker が関連 service worker でない場合、continue

      4. clienttargetClients に追加する。

    3. matchedWindowData を新しい リスト とする。

    4. matchedClients を新しい リスト とする。

    5. targetClients 内の各 service worker client client について:

      1. options["type"] が "window" または "all" であり、 clientenvironment settings object でない、または window client である場合:

        1. windowData を «[ "client" → client, "ancestorOriginsList" → 新しい リスト ]» とする。

        2. browsingContext を null とする。

        3. isClientEnumerable を true とする。

        4. clientenvironment settings object なら、browsingContextclientグローバルオブジェクト閲覧コンテキスト とする。

        5. そうでなければ、browsingContextclientターゲット閲覧コンテキスト とする。

        6. タスクをキューに入れる。以下のサブステップを browsingContextイベントループユーザー操作タスクソース を使って実行する:

          1. browsingContext破棄済み なら、isClientEnumerable を false にしてこれらの手順を中止する。

          2. client がwindow clientかつ client関連ドキュメントbrowsingContextアクティブドキュメント でない場合、isClientEnumerable を false にしてこれらの手順を中止する。

          3. windowData["frameType"] に Get Frame TypebrowsingContext で実行した結果を設定する。

          4. windowData["visibilityState"] に browsingContextアクティブドキュメントvisibilityState 属性値を設定する。

          5. windowData["focusState"] に has focus手順browsingContextアクティブドキュメント に対して実行した結果を設定する。

          6. clientwindow client なら、 windowData["ancestorOriginsList"] に browsingContextアクティブドキュメント該当グローバルオブジェクトLocation オブジェクトの 先祖オリジンリスト の関連リストを設定する。

        7. task が実行されるまで待つ。

          注: 待機はブロッキングだが、実装者は状態が壊れない限り並行して反復処理できる。

        8. isClientEnumerable が true なら:

          1. windowDatamatchedWindowData に追加する。

      2. そうでなく options["type"] が "worker" または "all" かつ clientdedicated worker client の場合、あるいは options["type"] が "sharedworker" または "all" かつ clientshared worker client の場合:

        1. clientmatchedClients に追加する。

    6. タスクをキューに入れる。以下の手順を promise該当設定オブジェクト責任イベントループDOM操作タスクソース を使って実行する:

      1. clientObjects を新しい リスト とする。

      2. windowData について、matchedWindowData 内で:

        1. windowClientCreate Window Client アルゴリズムを windowData["client"], windowData["frameType"], windowData["visibilityState"], windowData["focusState"], windowData["ancestorOriginsList"] で実行した結果とする。

        2. windowClientclientObjects に追加する。

      3. client について、matchedClients 内で:

        1. clientObjectCreate Client アルゴリズムを client で実行した結果とする。

        2. clientObjectclientObjects に追加する。

      4. clientObjects を以下のようにソートする:

        注: window client は常に worker client より先に配置される。

      5. promiseclientObjectsの新しいFrozenArraypromise該当Realm で解決する。

  3. promise を返す。

4.3.3. openWindow(url)

openWindow(url) メソッドの手順:

  1. urlパースした結果とし、this該当設定オブジェクトAPIベースURL を使う。

  2. url が失敗の場合、TypeError で拒否された promise を返す。

  3. urlabout:blank の場合、TypeError で拒否された promise を返す。

  4. この オリジンWindow が一つも 一時的なアクティベーション を持たない場合、"InvalidAccessError" DOMException で拒否された promise を返す。

  5. serviceWorkerEventLoop現在のグローバルオブジェクトイベントループ とする。

  6. promise を新しい promise とする。

  7. 以下のサブステップを 並行して実行する:

    1. newContext を新しい トップレベル閲覧コンテキスト とする。

    2. タスクをキューに入れる。以下の手順を newContextWindow オブジェクトの environment settings object責任イベントループユーザー操作タスクソース を使って実行する:

      1. HandleNavigate: ナビゲート newContexturl へ、例外有効 を true、historyHandling を "replace" とする。

      2. HandleNavigate ラベル付きのアルゴリズム手順が 例外 を投げた場合、タスクをキューに入れるpromise を例外で serviceWorkerEventLoop 上の DOM操作タスクソース で拒否し、これらの手順を中止する。

      3. frameTypeGet Frame TypenewContext で実行した結果とする。

      4. visibilityStatenewContextアクティブドキュメントvisibilityState 属性値とする。

      5. focusStatehas focus手順newContextアクティブドキュメント に対して実行した結果とする。

      6. ancestorOriginsListnewContextアクティブドキュメント該当グローバルオブジェクトLocation オブジェクトの 先祖オリジンリスト の関連リストとする。

      7. タスクをキューに入れる。以下の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:

        1. newContextWindow オブジェクトの environment settings objectストレージキーの取得 の結果が、equal でない場合、service worker含まれるService Worker登録ストレージキー と、promise を null で解決し、これらの手順を中止する。

        2. clientCreate Window ClientnewContextWindow オブジェクトの environment settings objectframeTypevisibilityStatefocusStateancestorOriginsList を渡して実行した結果とする。

        3. promiseclient で解決する。

  8. promise を返す。

4.3.4. claim()

claim() メソッドの手順:

  1. service workerアクティブワーカー でない場合、"InvalidStateError" DOMException で拒否された promise を返す。

  2. promise を新しい promise とする。

  3. 以下のサブステップを 並行して実行する:

    1. service worker client client について、ストレージキーの取得 の結果が、equal である場合、service worker含まれるService Worker登録ストレージキー と等しい場合:

      1. client実行準備フラグ が未設定、または client破棄フラグ が設定されている場合、continue

      2. clientセキュアコンテキスト でない場合、continue

      3. storage keyストレージキーの取得client で実行した結果とする。

      4. registrationMatch Service Worker Registrationstorage keyclient作成URL で実行した結果とする。

      5. registrationservice worker含まれるService Worker登録 でない場合、continue

        注: registration は、service worker含まれるService Worker登録登録解除済み の場合、null になる。

      6. clientactive service workerservice worker でない場合、以下を実行する:

        1. Handle Service Worker Client Unloadclient で呼び出す。

        2. clientactive service workerservice worker に設定する。

        3. Notify Controller Change アルゴリズムを client で呼び出す。

    2. promise を undefined で解決する。

  4. promise を返す。

4.4. ExtendableEvent

[Exposed=ServiceWorker]
interface ExtendableEvent : Event {
  constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
  undefined waitUntil(Promise<any> f);
};
dictionary ExtendableEventInit : EventInit {
  // 派生イベントに対する将来の互換性のために定義
};

ExtendableEvent オブジェクトは、関連付けられた extend lifetime promises(存続期間拡張promise群)promiseの配列)を持ちます。初期値は空配列です。

ExtendableEvent オブジェクトは、関連付けられた pending promises count(保留中promise数)extend lifetime promisesの中で保留中のpromise数)を持ちます。初期値は0です。

ExtendableEvent オブジェクトは、関連付けられた timed out flag(タイムアウトフラグ) を持ちます。これは初期状態では未設定であり、pending promises count が0より大きい場合、ユーザーエージェントが任意で遅延をかけた後に設定されます。

ExtendableEvent オブジェクトは、timed out flag が未設定であり、かつpending promises count が0より大きい、またはdispatch flag が設定されている場合、active(有効)であると言います。

Service Worker には2つのライフサイクルイベントinstallactivate)があります。 Service Worker は、ExtendableEvent インターフェースを install および activate イベントで利用します。

Service Worker拡張イベントハンドラを定義するものも、ExtendableEvent インターフェースを利用または拡張することができます

4.4.1. event.waitUntil(f)

注: waitUntil() メソッドはイベントの存続期間を延長します。

waitUntil(f) メソッドの手順は、lifetime promiseの追加 fthis に対して行うことです。

lifetime promiseの追加 promisepromise)を eventExtendableEvent)に対して行う手順:
  1. eventisTrusted 属性がfalseの場合、"InvalidStateError" DOMExceptionthrowする。

  2. eventactive でない場合、"InvalidStateError" DOMExceptionthrowする。

    注: イベントハンドラを呼び出したタスク内でlifetime extension promiseが追加されていない場合、後続の非同期タスクで waitUntil() を呼ぶと例外となります。

  3. promiseeventextend lifetime promises に追加する。

  4. eventpending promises count を1増加させる。

    注: 渡されたpromiseが既に解決済みでもpending promises countは加算されます。減算はpromiseのreactionでマイクロタスクがキューされる際に行われます。

  5. fulfillment または rejection が発生したら、マイクロタスクをキューして以下のサブステップを実行する:

    1. eventpending promises count を1減らす。

    2. eventpending promises count が0なら:

      1. registration現在のグローバルオブジェクト の関連 service worker含まれるService Worker登録 とする。

      2. registration登録解除済み なら、Try Clear Registrationregistration で呼ぶ。

      3. registration が null でない場合、Try Activateregistration で呼ぶ。

ユーザーエージェントは、Service Worker Has No Pending Events がその service worker に対してfalseを返す場合、service workerの終了すべきではないです。

Service Worker拡張イベントハンドラを定義するものは、独自の挙動を定義できます。これらはextend lifetime promisesによって処理の長さを示唆したり、promiseがrejectされた場合は処理の失敗を示唆できます。

注: Service Workerinstalling worker を"installed"として扱うのを、install イベントの extend lifetime promises が全て正常解決するまで遅延します(Installアルゴリズムステップ参照)。promiseがrejectされるとインストールは失敗となります。これは主に service worker のコアキャッシュが全て準備完了してからインストール済みとみなすために使われます。同様に service workeractive worker を"activated"として扱うのを、activate イベントの extend lifetime promises が解決するまで遅延します(Activateアルゴリズムステップ参照)。これは、functional events が、DBスキーマの更新や不要なキャッシュ削除が終わるまでdispatchされないようにするために使われます。

4.5. InstallEvent

[Exposed=ServiceWorker]
interface InstallEvent : ExtendableEvent {
  constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
  Promise<undefined> addRoutes((RouterRule or sequence<RouterRule>) rules);
};

dictionary RouterRule {
  required RouterCondition condition;
  required RouterSource source;
};

dictionary RouterCondition {
  URLPatternCompatible urlPattern;
  ByteString requestMethod;
  RequestMode requestMode;
  RequestDestination requestDestination;
  RunningStatus runningStatus;

  sequence<RouterCondition> _or;
  RouterCondition not;
};

typedef (RouterSourceDict or RouterSourceEnum) RouterSource;

dictionary RouterSourceDict {
  DOMString cacheName;
};

enum RunningStatus { "running", "not-running" };
enum RouterSourceEnum {
  "cache",
  "fetch-event",
  "network",
  "race-network-and-fetch-handler"
};

count router condition result(ルーター条件結果のカウント)は、次からなる構造体です:

  • condition count(条件数)(数値)。

  • quota exceeded(クォータ超過)(真偽値)。

4.5.1. event.addRoutes(rules)

注: addRoutes(rules) は、このサービスワーカーでfetchイベントハンドラが通常行う単純なタスクを分担するためのルールを登録します。

addRoutes(rules) メソッドの手順:

  1. rulesRouterRule 辞書のときは、rules を « rules » に設定する。

  2. serviceWorker現在のグローバルオブジェクト の関連 service worker とする。

  3. rules の各 rule について:

    1. Verify Router Condition アルゴリズムを rule["condition"] と serviceWorker で実行して false なら、promiseで拒否し、TypeError を返す。

    2. rule["source"] が "fetch-event" または "race-network-and-fetch-handler" のいずれかで、 serviceWorker処理するイベント型の集合fetch イベントを含んでいなければ、 promiseで拒否し、TypeError を返す。

  4. lifetimePromise を新しい promise とする。

  5. lifetime promiseの追加 lifetimePromisethis に対して行う。

    注: event.addRoutes(rules)event.waitUntil(promise) が呼ばれるのと同様に、デフォルトでイベントの存続期間を延長します。

  6. promise を新しい promise とする。

  7. fulfillment または rejectionpromise で発生したら、 lifetimePromise を undefined で解決する。

    注: このステップは install イベント失敗を避けるため、lifetimePromise を必ずfulfilledにします。

  8. 以下の手順をエンキューして [[service worker queue]] で実行する:

    1. allRulesserviceWorkerルーター規則リスト のコピーとする。

    2. rules の各 rule について:

      1. ruleallRules に追加する。

    3. Check Router Registration LimitallRules に対して実行して false なら、promiseTypeError で拒否する。

    4. serviceWorkerルーター規則リストallRules に設定する。

    5. serviceWorkerEventLoop現在のグローバルオブジェクトイベントループ とする。

    6. タスクをキューに入れる。以下の手順を serviceWorkerEventLoop 上で DOM操作タスクソース を使って実行する:

      1. promise を undefined で解決する。

  9. promise を返す。

4.6. FetchEvent

[Exposed=ServiceWorker]
interface FetchEvent : ExtendableEvent {
  constructor(DOMString type, FetchEventInit eventInitDict);
  [SameObject] readonly attribute Request request;
  readonly attribute Promise<any> preloadResponse;
  readonly attribute DOMString clientId;
  readonly attribute DOMString resultingClientId;
  readonly attribute DOMString replacesClientId;
  readonly attribute Promise<undefined> handled;

  undefined respondWith(Promise<Response> r);
};
dictionary FetchEventInit : ExtendableEventInit {
  required Request request;
  Promise<any> preloadResponse;
  DOMString clientId = "";
  DOMString resultingClientId = "";
  DOMString replacesClientId = "";
  Promise<undefined> handled;
};

ServiceWorker には重要な機能的イベント fetch があります。 fetch イベントでは、ServiceWorkerFetchEvent インターフェースを利用し、これは ExtendableEvent インターフェースを拡張します。

FetchEvent インターフェースを使用する各イベントには、関連付けられた potential response(潜在的レスポンス)response)があり、初期値はnullです。また、初期状態で未設定の以下のフラグを持ちます:

  • wait to respond flag(応答待ちフラグ)

  • respond-with entered flag(respondWith実行済みフラグ)

  • respond-with error flag(respondWithエラーフラグ)

4.6.1. event.request

request 属性は、初期化時に設定された値を返すべきです。

4.6.2. event.preloadResponse

preloadResponse 属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は undefinedで解決されたpromise に初期化すべきです。

4.6.3. event.clientId

clientId 属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。

4.6.4. event.resultingClientId

resultingClientId 属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。

4.6.5. event.replacesClientId

replacesClientId 属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。

4.6.6. event.handled

handled 属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性はpendingな promise で初期化すべきです。

4.6.7. event.respondWith(r)

注: 開発者は引数 rpromiseResponse オブジェクトで解決される)または Response オブジェクト(自動的にpromiseへ変換)を指定できます。それ以外の場合は ネットワークエラーFetch に返されます。 レンダラー側のクロスオリジンコンテンツの汚染に関するセキュリティチェックは、filtered response の型に依存します。

respondWith(r) メソッドの手順:

  1. eventthis とする。

  2. eventdispatch flag が未設定なら、"InvalidStateError" DOMExceptionthrowする。

  3. eventrespond-with entered flag が 設定済みなら、"InvalidStateError" DOMExceptionthrowする。

  4. lifetime promiseの追加 revent に対して行う。

    注: event.respondWith(r)event.waitUntil(r) を呼ぶのと同様に、デフォルトでイベントの存続期間を延長します。

  5. eventstop propagation flag および stop immediate propagation flag を設定する。

  6. eventrespond-with entered flag を設定する。

  7. eventwait to respond flag を設定する。

  8. targetRealmeventrelevant Realm とする。

  9. rのrejection時:

    1. eventrespond-with error flag を設定する。

    2. eventwait to respond flag を解除する。

  10. rのfulfillment時response で:

    1. responseResponse オブジェクトでない場合、respond-with error flag を設定する。

      注: respond-with error flag が設定された場合、 ネットワークエラーFetchHandle Fetch アルゴリズムを通じて返されます(ステップ21.1参照)。そうでなければ、値 responseFetchHandle Fetch アルゴリズムを通じて返されます(ステップ22.1参照)。

    2. それ以外の場合:

      1. bytes を空のバイト列とする。

      2. end-of-body をfalseとする。

      3. done をfalseとする。

      4. potentialResponseresponse の関連付けられた response のコピーとし、body を除く。

      5. responsebody がnullでない場合、以下のサブステップを実行:

        1. readerreader取得responsebodystream で実行した結果とする。

        2. pullAlgorithm を以下を行うactionとする:

          1. readRequest を新しい read request とし、以下の item を持つ:

            chunk stepschunkを受け取る)
            1. アサート:chunkUint8Array である。

            2. chunk で表されるバイトを bytes に追加する。

            3. potentialResponsebody infoencoded sizebytesbyte length だけ増加させる。

            4. potentialResponsebody infodecoded sizebytesbyte length だけ増加させる。

            5. ! DetachArrayBuffer(chunk.[[ViewedArrayBuffer]]) を実行する。

            close steps
            1. end-of-body をtrueにする。

            error steps
            1. error newStreamTypeError を与える。

          2. read a chunkreaderreadRequest を与えて実行する。

        3. cancelAlgorithmreaderのキャンセルアクションとする。

        4. highWaterMark を非負・非NaNな数値(ユーザーエージェントが決定)とする。

        5. sizeAlgorithmchunk オブジェクトを受け取り、非負・非NaN・無限大でない値を返すアルゴリズム(ユーザーエージェントが決定)とする。

        6. newStream を新しい ReadableStream とし、set uppullAlgorithm pullAlgorithmcancelAlgorithm cancelAlgorithmhighWaterMark highWaterMarksizeAlgorithm sizeAlgorithmtargetRealm でセットアップする。

        7. potentialResponsebody を新しい body とし、その streamnewStream にする。

        8. 以下を 並行して done がfalseの間繰り返す:

          1. newStreamerrored なら、done をtrueにする。

          2. それ以外で bytes が空かつ end-of-body がtrueなら、close newStreamdone をtrueにする。

          3. それ以外で bytes が空でない場合、以下のサブサブサブステップを実行:

            1. chunkbytes の先頭からの部分列とする。

            2. chunkbytes から除去する。

            3. buffertargetRealm で作られた ArrayBuffer オブジェクトで、chunk を含むものとする。

            4. enqueuetargetRealm で作られた Uint8Array オブジェクトで buffer をラップし、newStream に追加する。

        注: これらのサブステップは responsebodystreampotentialResponse に「パイプ」する観測可能な同等物を生成するためのものです。

        注: ServiceWorkerがチャンクで書き込んだデータは、受け取ったクライアントが必ずしも同じチャンクで読むとは限りません。つまり、クライアントは同じ内容を読むが、ブラウザによってチャンク分割方法が異なる場合があります。

      6. eventpotential responsepotentialResponse に設定する。

    3. eventwait to respond flag を解除する。

4.7. ExtendableMessageEvent

[Exposed=ServiceWorker]
interface ExtendableMessageEvent : ExtendableEvent {
  constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict = {});
  readonly attribute any data;
  readonly attribute USVString origin;
  readonly attribute DOMString lastEventId;
  [SameObject] readonly attribute (Client or ServiceWorker or MessagePort)? source;
  readonly attribute FrozenArray<MessagePort> ports;
};
dictionary ExtendableMessageEventInit : ExtendableEventInit {
  any data = null;
  USVString origin = "";
  DOMString lastEventId = "";
  (Client or ServiceWorker or MessagePort)? source = null;
  sequence<MessagePort> ports = [];
};

ServiceWorkerextendable message イベントを定義し、イベントの存続期間を延長できるようにします。message イベントでは、ServiceWorkerExtendableMessageEvent インターフェースを利用し、これは ExtendableEvent インターフェースを拡張します。

4.7.1. event.data

data 属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性はnullで初期化すべきです。送信されるメッセージを表します。

4.7.2. event.origin

origin 属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性は空文字列で初期化すべきです。これはメッセージを送信したオリジンを表します。

4.7.3. event.lastEventId

lastEventId 属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性は空文字列で初期化すべきです。

4.7.4. event.source

source 属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性はnullで初期化すべきです。これはメッセージを送信した Client オブジェクトを表します。

4.7.5. event.ports

ports 属性は、初期化時に設定された値を返すべきです。オブジェクト生成時にはこの属性は空配列で初期化すべきです。これは送信される MessagePort 配列を表します。

4.8. イベント

以下のイベントは ServiceWorkerイベント と呼ばれ、ServiceWorkerGlobalScope オブジェクト上でdispatchされます:

イベント名 インターフェース カテゴリ dispatch時の条件
install InstallEvent ライフサイクル ServiceWorker含まれるServiceWorker登録installing worker が変化したとき(Installアルゴリズムステップ11.2参照)
activate ExtendableEvent ライフサイクル ServiceWorker含まれるServiceWorker登録active worker が変化したとき(Activateアルゴリズムステップ12.2参照)
fetch FetchEvent 機能 http fetchHandle Fetchrequest で呼び出したとき。その結果、Handle Fetch の実行により、ServiceWorkerresponsehttp fetch に返す。Response オブジェクトは Cache オブジェクトから取得するか、self.fetch(input, init) メソッドでネットワークから直接取得できる。(カスタム Response オブジェクトも選択肢となる。)
push PushEvent 機能 pushイベントの発火参照)
notificationclick NotificationEvent 機能 通知のアクティベート参照)
notificationclose NotificationEvent 機能 通知のクローズ参照)
sync SyncEvent 機能 syncイベントの発火参照)
canmakepayment CanMakePaymentEvent 機能 CanMakePaymentEventの処理参照)
paymentrequest PaymentRequestEvent 機能 PaymentRequestEventの処理参照)
message ExtendableMessageEvent レガシー メッセージ受信時
messageerror MessageEvent レガシー デシリアライズできないメッセージ受信時

5. キャッシュ

著者がオフライン利用のためにコンテンツキャッシュを完全に管理できるよう、Window および WorkerGlobalScope は、Cache オブジェクトを開いて操作できる非同期キャッシュメソッドを提供します。オリジンごとに複数の名前付き Cache オブジェクトを持つことができ、その内容は完全にスクリプトで制御できます。キャッシュは オリジン間で共有されず、ブラウザのHTTPキャッシュとも完全に分離されています。

5.1. 構成要素

リクエスト・レスポンスリストは、リストであり、タプルリクエストレスポンス)で構成されます。

関連リクエスト・レスポンスリストは、thisが表すインスタンスです。

名前 → キャッシュマップは、順序付きマップであり、エントリーキーリクエスト・レスポンスリストの名前を表す文字列)と リクエスト・レスポンスリスト)で構成されます。

ストレージキーは、関連付けられた名前 → キャッシュマップを持ちます。

関連名前 → キャッシュマップは、名前 → キャッシュマップであり、ストレージキー取得したものに、thisの関連するグローバルオブジェクト環境設定オブジェクトが使われます。

5.2. キャッシュの寿命の理解

Cache インスタンスはブラウザのHTTPキャッシュとは無関係です。Cache オブジェクトは著者が自ら管理するものです。Cache オブジェクトは、著者が明示的に更新を要求しない限り更新されません。Cache オブジェクトは、著者がエントリーを削除しない限り期限切れになりません。Cache オブジェクトは、ServiceWorkerスクリプトが更新されても消えません。つまり、キャッシュは自動で更新されません。更新は手動で管理する必要があります。したがって、著者はキャッシュ名でバージョン管理し、ServiceWorkerの安全に操作できるバージョンのキャッシュのみ利用するようにしてください。

5.3. self.caches

partial interface mixin WindowOrWorkerGlobalScope {
  [SecureContext, SameObject] readonly attribute CacheStorage caches;
};

5.3.1. caches

caches のgetter手順は、thisの関連付けられたCacheStorageオブジェクトを返します。

5.4. Cache

[SecureContext, Exposed=(Window,Worker)]
interface Cache {
  [NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<undefined> add(RequestInfo request);
  [NewObject] Promise<undefined> addAll(sequence<RequestInfo> requests);
  [NewObject] Promise<undefined> put(RequestInfo request, Response response);
  [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options = {});
};
dictionary CacheQueryOptions {
  boolean ignoreSearch = false;
  boolean ignoreMethod = false;
  boolean ignoreVary = false;
};

Cache オブジェクトは、リクエスト・レスポンスリストを表します。複数のドキュメントやワーカー間で Cache インターフェースを実装する別々のオブジェクトが、同じ リクエスト・レスポンスリスト に関連付けられる場合もあります。

キャッシュバッチ操作は、構造体であり、次の要素からなります:

5.4.1. match(request, options)

match(request, options) メソッドの手順:

  1. promise新しいpromise とする。

  2. 以下のサブステップを 並行して実行する:

    1. pmatchAll(request, options) メソッド(requestoptionsを渡す)で実行したアルゴリズムの結果とする。

    2. p がsettleするまで待つ。

    3. p が例外でrejectされたら:

      1. promise をその例外でrejectする。

    4. p が配列responsesでresolveされた場合:

      1. responses が空配列の場合:

        1. promise をundefinedでresolveする。

      2. それ以外の場合:

        1. promiseresponsesの最初の要素でresolveする。

  3. promise を返す。

5.4.2. matchAll(request, options)

matchAll(request, options) メソッドの手順:

  1. r をnullとする。

  2. オプション引数requestが省略されていない場合:

    1. requestRequest オブジェクトなら:

      1. rrequestrequest とする。

      2. rmethod が `GET` でなく、かつ options.ignoreMethod がfalseなら、空配列でresolveされたpromise を返す。

    2. そうでなくrequestが文字列なら:

      1. rrequest を引数として Request のコンストラクタを呼び出した結果の関連 request とする。例外が発生したら その例外でrejectされたpromise を返す。

  3. realmthis関連Realm とする。

  4. promise新しいpromise とする。

  5. 以下のサブステップを 並行して実行する:

    1. responses を空の リスト とする。

    2. オプション引数requestが省略されている場合:

      1. requestResponse について、関連リクエスト・レスポンスリスト内で:

        1. requestResponse のレスポンスのコピーを responses に追加する。

    3. そうでない場合:

      1. requestResponsesQuery Cacheroptions で実行した結果とする。

      2. requestResponse について、requestResponses内で:

        1. requestResponse のレスポンスのコピーを responses に追加する。

    4. response について、responses内で:

      1. responsetype が "opaque" かつ cross-origin resource policy checkpromise関連設定オブジェクトoriginpromise関連設定オブジェクト、空文字列、responseinternal response で実行)がblockedを返した場合、promiseTypeError でrejectし、これらの手順を中止する。

    5. タスクをキューに入れるpromise関連設定オブジェクト責任イベントループDOM操作タスクソース を使い、以下の手順を実行する:

      1. responseListリストとする。

      2. response について、responses内で:

        1. 新しい Response オブジェクト(responseに関連付け、Headers オブジェクト(guard が "immutable")付き)を responseList に追加する。

      3. promisefrozen arrayresponseListから生成realmで)でresolveする。

  6. promise を返す。

5.4.3. add(request)

add(request) メソッドの手順:

  1. requestsrequest だけを含む配列とする。

  2. responseArrayPromiseaddAll(requests) のアルゴリズム(requestsを引数に)で実行した結果とする。

  3. responseArrayPromise のsettle後にundefinedを返すfulfillmentハンドラで reactする結果を返す。

5.4.4. addAll(requests)

addAll(requests) メソッドの手順:

  1. responsePromises を空の リストとする。

  2. requestList を空の リストとする。

  3. requests 内の Request 型の各 request について:

    1. rrequestrequest とする。

    2. rurlscheme が "http" または "https" 以外の場合、もしくは rmethod が `GET` でない場合、TypeErrorでrejectされたpromise を返す。

  4. fetchControllersリストfetch controller)とする。

  5. requests の各 request について:

    1. rrequest を引数に Request のコンストラクタを呼び出した結果の関連 request とする。例外が発生したら 例外でrejectされたpromise を返す。

    2. rurlscheme が "http" または "https" 以外の場合:

      1. fetchController について、fetchControllers内で、abortする。

      2. TypeErrorでrejectされたpromise を返す。

    3. rclientglobal objectServiceWorkerGlobalScope オブジェクトなら、requestservice-workers mode を "none" に設定する。

    4. rinitiator を "fetch"、destination を "subresource" に設定する。

    5. requestListr を追加する。

    6. responsePromise新しいpromiseとする。

    7. 以下のサブステップを 並行して実行する:

      • fetching r の結果を追加する。

      • processResponseresponse に対して実行:

        1. responsetype が "error"、または responsestatusok status 以外、または 206 の場合、responsePromiseTypeError でrejectする。

        2. それ以外で responseheader listheader Vary が含まれる場合:

          1. fieldValueslistfield-valuesVary headerで抽出)とする。

          2. fieldValue について、fieldValues内で:

            1. fieldValue が "*" と一致する場合:

              1. responsePromiseTypeError でrejectする。

              2. fetchController について、fetchControllers内で、abortする。

              3. これらの手順を中止する。

      • processResponseEndOfBodyresponse に対して実行:

        1. responseaborted flag が設定されている場合、"AbortError" DOMExceptionresponsePromise をrejectし、これらの手順を中止する。

        2. responsePromiseresponse でresolveする。

        注: レスポンスのbodyが完全に受信されたときにキャッシュコミットが許可されます。

    8. responsePromiseresponsePromises に追加する。

  6. presponsePromises全部がsettleするpromiseの結果とする。

  7. p のsettle後、引数 responses を受け取るfulfillmentハンドラで reactし、以下のサブステップを実行:

    1. operations を空の リストとする。

    2. index をゼロとする。

    3. responses の各 response について:

      1. operationキャッシュバッチ操作とする。

      2. operationtype を "put" に設定する。

      3. operationrequestrequestList[index] に設定する。

      4. operationresponseresponse に設定する。

      5. operationoperations に追加する。

      6. index を1増やす。

    4. realmthis関連Realmとする。

    5. cacheJobPromise新しいpromiseとする。

    6. 以下のサブステップを 並行して実行する:

      1. errorData をnullとする。

      2. Batch Cache Operationsoperations で呼び出す。例外が発生したら errorData にその例外を設定する。

      3. タスクをキューに入れるcacheJobPromise関連設定オブジェクト責任イベントループDOM操作タスクソース を使い、以下のサブステップを実行:

        1. errorData がnullなら cacheJobPromise をundefinedでresolveする。

        2. それ以外なら cacheJobPromise新規例外exceptionerrorDatarealm)でrejectする。

    7. cacheJobPromise を返す。

5.4.5. put(request, response)

put(request, response) メソッドの手順:

  1. innerRequest を null とする。

  2. requestRequest オブジェクトの場合、innerRequestrequestrequest に設定する。

  3. それ以外の場合:

    1. requestObjRequest のコンストラクタに request を渡して呼び出した結果とする。例外が発生した場合は その例外でrejectされたpromise を返す。

    2. innerRequestrequestObjrequest に設定する。

  4. innerRequesturlscheme が "http" または "https" 以外の場合、または innerRequestmethod が `GET` でない場合、TypeErrorでrejectされたpromise を返す。

  5. innerResponseresponseresponse に設定する。

  6. innerResponsestatus206 の場合、TypeErrorでrejectされたpromise を返す。

  7. innerResponseheader listheader Vary が含まれる場合:

    1. fieldValueslistVary header の field-values)とする。

    2. fieldValue について、fieldValues内で:

      1. fieldValue が "*" と一致する場合、TypeErrorでrejectされたpromise を返す。

  8. innerResponsebodydisturbed または locked の場合、TypeErrorでrejectされたpromise を返す。

  9. clonedResponseinnerResponseのclone とする。

  10. bodyReadPromiseundefinedでresolveされたpromise とする。

  11. innerResponsebody が null でない場合、以下のサブステップを実行:

    1. streaminnerResponsebodystream に設定する。

    2. readerstreamのreader取得の結果とする。

    3. bodyReadPromise全バイト読み取りreader で実行した結果とする。

    注: これは innerResponsebodylocked になり、clonedResponse に完全なバッファ済みコピーを保持することを保証します。実装ではメモリではなく直接ディスクにストリームする最適化も可能です。

  12. operations を空の リストとする。

  13. operationキャッシュバッチ操作とする。

  14. operationtype を "put" に設定する。

  15. operationrequestinnerRequest に設定する。

  16. operationresponseclonedResponse に設定する。

  17. operationoperations に追加する。

  18. realmthis関連Realmとする。

  19. bodyReadPromisefulfillment時に以下を実行:

    1. cacheJobPromise新しいpromiseとする。

    2. cacheJobPromise を返し、以下のサブステップを 並行して実行:

      1. errorData を null とする。

      2. Batch Cache Operationsoperations で呼び出す。例外が発生したら errorData にその例外を設定する。

      3. タスクをキューに入れるcacheJobPromise関連設定オブジェクト責任イベントループDOM操作タスクソース を使い、以下のサブステップを実行:

        1. errorData が null なら cacheJobPromise を undefined でresolveする。

        2. それ以外なら cacheJobPromise新規例外exceptionerrorDatarealm)でrejectする。

5.4.6. delete(request, options)

delete(request, options) メソッドの手順:

  1. r を null とする。

  2. requestRequest オブジェクトの場合:

    1. rrequestrequest に設定する。

    2. rmethod が `GET` でなく、かつ options.ignoreMethod が false なら falseでresolveされたpromise を返す。

  3. そうでなくrequestが文字列の場合:

    1. rrequest を引数として Request のコンストラクタを呼び出した結果の関連 request とする。例外が発生した場合は その例外でrejectされたpromise を返す。

  4. operations を空の リストとする。

  5. operationキャッシュバッチ操作とする。

  6. operationtype を "delete" に設定する。

  7. operationrequestr に設定する。

  8. operationoptionsoptions に設定する。

  9. operationoperations に追加する。

  10. realmthis関連Realmとする。

  11. cacheJobPromise新しいpromiseとする。

  12. 以下のサブステップを 並行して実行:

    1. errorData を null とする。

    2. requestResponsesBatch Cache Operationsoperations で呼び出した結果とする。例外が発生したら errorData にその例外を設定する。

    3. タスクをキューに入れるcacheJobPromise関連設定オブジェクト責任イベントループDOM操作タスクソース を使い、以下のサブステップを実行:

      1. errorData が null なら:

        1. requestResponses空でない場合、cacheJobPromise を true でresolveする。

        2. それ以外なら cacheJobPromise を false でresolveする。

      2. それ以外なら cacheJobPromise新規例外exceptionerrorDatarealm)でrejectする。

  13. cacheJobPromise を返す。

5.4.7. keys(request, options)

keys(request, options) メソッドの手順:

  1. r を null とする。

  2. オプション引数requestが省略されていない場合:

    1. requestRequest オブジェクトの場合:

      1. rrequestrequest に設定する。

      2. rmethod が `GET` でなく、かつ options.ignoreMethod がfalseなら、空配列でresolveされたpromise を返す。

    2. そうでなくrequestが文字列の場合:

      1. rrequest を引数に Request のコンストラクタを呼び出した結果の関連 request とする。例外が発生した場合は その例外でrejectされたpromise を返す。

  3. realmthis関連Realmとする。

  4. promise新しいpromiseとする。

  5. 以下のサブステップを 並行して実行:

    1. requests を空の リストとする。

    2. オプション引数requestが省略されている場合:

      1. requestResponse について、関連リクエスト・レスポンスリスト内で:

        1. requestResponse のリクエストを requests に追加する。

    3. そうでない場合:

      1. requestResponsesQuery Cacheroptions で実行した結果とする。

      2. requestResponse について、requestResponses内で:

        1. requestResponse のリクエストを requests に追加する。

    4. タスクをキューに入れるpromise関連設定オブジェクト責任イベントループDOM操作タスクソース を使い、以下の手順を実行:

      1. requestListリストとする。

      2. request について、requests内で:

        1. 新しい Request オブジェクト(requestに関連付け、Headers オブジェクト(guard が "immutable")付き)を requestList に追加する。

      3. promisefrozen arrayrequestListから生成realmで)でresolveする。

  6. promise を返す。

5.5. CacheStorage

[SecureContext, Exposed=(Window,Worker)]
interface CacheStorage {
  [NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional MultiCacheQueryOptions options = {});
  [NewObject] Promise<boolean> has(DOMString cacheName);
  [NewObject] Promise<Cache> open(DOMString cacheName);
  [NewObject] Promise<boolean> delete(DOMString cacheName);
  [NewObject] Promise<sequence<DOMString>> keys();
};

dictionary MultiCacheQueryOptions : CacheQueryOptions {
  DOMString cacheName;
};

注: CacheStorage インターフェースは基本的に ECMAScript 6 のMapオブジェクトに準拠して設計されていますが、完全に非同期で、追加の便利なメソッドも備えています。clearforEachentriesvalues メソッドは、TC39によるasyncイテレーションの議論に依存するため初版では意図的に除外されています。

ユーザーエージェントは CacheStorage オブジェクトを、Window オブジェクトまたは WorkerGlobalScope オブジェクト生成時に作成し、その グローバルオブジェクト に関連付ける必要があります

CacheStorage オブジェクトは、関連付けられた グローバルオブジェクト環境設定オブジェクトオリジン に紐付く 名前 → キャッシュマップ を表します。複数のドキュメントやワーカーで CacheStorage インターフェースを実装する別々のオブジェクトが、同じ 名前 → キャッシュマップ に同時に関連付けられる場合もあります。

5.5.1. match(request, options)

match(request, options) メソッドの手順:

  1. options["cacheName"] が存在する場合:

    1. 新しいpromise promise を返し、以下のサブステップを 並行して実行:

      1. cacheNamecache について、関連名前 → キャッシュマップ内で:

        1. options["cacheName"] が cacheName と一致する場合:

          1. match(request, options) メソッド(requestoptionsを渡す)を Cache インターフェースで実行し、その結果で promise をresolveする(thisArgumentとしてcacheを渡す)。

          2. これらの手順を中止する。

      2. promise をundefinedでresolveする。

  2. それ以外の場合:

    1. promiseundefinedでresolveされたpromise とする。

    2. cacheNamecache について、関連名前 → キャッシュマップ内で:

      1. promise を自身の settle後にreactするように設定し、引数 response を受け取るfulfillmentハンドラで以下を実行:

        1. response がundefinedでなければ response を返す。

        2. match(request, options) メソッド(requestoptionsを渡す)を Cache インターフェースで実行し、その結果を返す(thisArgumentとしてcacheを渡す)。

    3. promise を返す。

5.5.2. has(cacheName)

has(cacheName) メソッドの手順:

  1. promise新しいpromise とする。

  2. 以下のサブステップを 並行して実行:

    1. keyvalue について、関連名前 → キャッシュマップ内で:

      1. cacheNamekey と一致すれば promise を true でresolveし、これらの手順を中止する。

    2. promise を false でresolveする。

  3. promise を返す。

5.5.3. open(cacheName)

open(cacheName) メソッドの手順:

  1. promise新しいpromise とする。

  2. 以下のサブステップを 並行して実行:

    1. keyvalue について、関連名前 → キャッシュマップ内で:

      1. cacheNamekey と一致する場合:

        1. value を表す新しい Cache オブジェクトで promise をresolveする。

        2. これらの手順を中止する。

    2. cache を新しい リクエスト・レスポンスリスト とする。

    3. 関連名前 → キャッシュマップ[cacheName] に cache を設定する。このキャッシュ書き込み操作がクォータ制限超過で失敗した場合、promise を "QuotaExceededError" DOMException でrejectし、これらの手順を中止する。

    4. cache を表す新しい Cache オブジェクトで promise をresolveする。

  3. promise を返す。

5.5.4. delete(cacheName)

delete(cacheName) メソッドの手順:

  1. promisehas(cacheName) メソッドで cacheName を渡して実行したアルゴリズムの結果とする。

  2. promise のsettle後、引数 cacheExists を受け取るfulfillmentハンドラで reactし、以下のサブステップを実行:

    1. cacheExists がfalseの場合:

      1. false を返す。

    2. cacheJobPromise新しいpromiseとする。

    3. 以下のサブステップを 並行して実行:

      1. 関連名前 → キャッシュマップ[cacheName] を削除する。

      2. cacheJobPromise を true でresolveする。

      注: このステップ後、既存のDOMオブジェクト(参照中のCache、Request、Responseオブジェクト)は機能を維持します。

    4. cacheJobPromise を返す。

5.5.5. keys()

keys() メソッドの手順:

  1. promise新しいpromiseとする。

  2. 以下のサブステップを 並行して実行:

    1. cacheKeys関連名前 → キャッシュマップ のキー取得結果とする。

      注: 結果の item順序付き集合)は 名前 → キャッシュマップ に追加された順序です。

    2. promisecacheKeys でresolveする。

  3. promise を返す。

6. セキュリティに関する考慮事項

6.1. セキュアコンテキスト

ServiceWorker必ず セキュアコンテキスト で実行されなければなりません。ServiceWorkerクライアント必ず セキュアコンテキスト で、ServiceWorker登録の登録や、ServiceWorker登録ServiceWorkerへのアクセス、ServiceWorkerとのメッセージ送受信、ServiceWorkerによる操作ができる必要があります。

注: これは ServiceWorker および ServiceWorkerクライアント がHTTPSでホストされる必要があることを意味します。ユーザーエージェントは開発目的で localhost要件参照)、127.0.0.0/8::1/128 を許可できます。この制限の主な理由は、非セキュアコンテキストに関連するリスクからユーザーを保護するためです。

6.2. Content Security Policy(CSP)

ユーザーエージェントが Run Service Worker アルゴリズムを ServiceWorker serviceWorker で呼び出す際:

  • serviceWorkerスクリプトリソースContent-Security-Policy HTTPヘッダー値 policy で配信された場合、ユーザーエージェントは 必ず policyを強制 しなければなりません。

  • serviceWorkerスクリプトリソースContent-Security-Policy-Report-Only HTTPヘッダー値 policy で配信された場合、ユーザーエージェントは 必ず policyを監視 しなければなりません。

この制限の主な理由は、クロスサイトスクリプティング(XSS)などの幅広いコンテンツ注入脆弱性を緩和するためです。

6.3. オリジン依存性

6.3.1. オリジン制限

この節は規範的ではありません。

ServiceWorker は登録した ServiceWorkerクライアントオリジン で実行されます。大規模なアプリケーションで課題となるのはCDNからのホスト可否ですが、CDNは定義上他の場所や他の オリジン です。したがって、ServiceWorkerはCDNでホストできません。ただし importScripts() 経由でリソースを含めることは可能です。この制限理由は、ServiceWorkerが悪意ある者によって永続的な被害をもたらす可能性があるためです。

6.3.2. importScripts(urls)

importScripts(urls) メソッドが ServiceWorkerGlobalScope オブジェクトで呼ばれると、ユーザーエージェントは 必ず workerグローバルスコープへスクリプトをimportします(この ServiceWorkerGlobalScope オブジェクトと urls を渡す)。さらに fetchフック手順(リクエスト request に対し)を以下の通り実行します:

  1. serviceWorkerrequestclientグローバルオブジェクトServiceWorker とする。

  2. mapserviceWorkerスクリプトリソースマップ とする。

  3. urlrequesturl とする。

  4. serviceWorkerstate が "parsed" または "installing" でない場合:

    1. map[url] が存在すればそれを返し、そうでなければ ネットワークエラー を返す。

  5. map[url] が存在する場合:

    1. urlを serviceWorker使用済みスクリプト集合 に追加する。

    2. map[url] を返す。

  6. registrationserviceWorkerServiceWorker登録 とする。

  7. requestservice-workers mode を "none" に設定する。

  8. 次のいずれかに該当する場合 requestcache mode を "no-cache" に設定する:

  9. responserequestのfetch結果とする。

  10. responsecache state が "local" でない場合、registrationlast update check time を現在時刻に設定する。

  11. responseunsafe responsebad import script response なら ネットワークエラー を返す。

  12. map[url] に response を設定する。

  13. urlを serviceWorker使用済みスクリプト集合 に追加する。

  14. serviceWorkerクラシックスクリプトimport済みフラグ を設定する。

  15. response を返す。

6.4. クロスオリジンリソースとCORS

この節は規範的ではありません。

アプリケーションはCDN等、他の オリジン から取得したアイテムをキャッシュすることが多いです。<script><img><video><link> 等で直接取得できます。これらがオフラインで動作しなくなると制約が大きくなります。同様に、適切なCORSヘッダーがセットされた場合 fetch で様々なオフオリジンリソース取得も可能です。ServiceWorkerCache でオフオリジンアイテムのfetch・キャッシュを可能にします。ただし制限があります。同一オリジンリソースは CacheResponse オブジェクト(対応する responsebasic filtered response)として管理されますが、クロスオリジンリソースは Response オブジェクト(対応する responseCORS filtered response または opaque filtered response)として保存されます。これらは event.respondWith(r) で同様に渡せますが、プログラム的に意味ある形で生成はできません。こうした制約はプラットフォームのセキュリティ保証の維持に必要です。Cache で格納できることで、アプリの大半は再設計せずに済みます。

6.5. パス制限

この節は規範的ではありません。

オリジン制限に加え、ServiceWorkerはスクリプトの パス でも制限されます。例えば https://www.example.com/~bob/sw.js の ServiceWorkerは scope url https://www.example.com/~bob/ では登録できますが、https://www.example.com/https://www.example.com/~alice/ ではできません。これは同一オリジンでユーザーごとに分離されるディレクトリ構成のサイトの保護に役立ちます。ただしパス制限は厳密なセキュリティ境界ではなく、オリジンのみが厳密な境界です。サイトは必要に応じて異なるオリジンを用いて安全な分離を推奨します。

サーバーは ServiceWorker スクリプトに Service-Worker-Allowed ヘッダーを設定することでパス制限を解除できます。

6.6. ServiceWorkerスクリプトリクエスト

この節は規範的ではありません。

悪意あるServiceWorker登録への対策として、本仕様は以下を要求します:

6.7. 実装者向け注意事項

この節は規範的ではありません。

実装者は以下に留意してください:

  • プラグインは ServiceWorker 経由ではロードすべきではありません。プラグインは自身のURLからセキュリティオリジンを取得する場合があり、埋め込んだ ServiceWorker では扱えません。このため Handle Fetch アルゴリズムは <embed> および <object> リクエストを fetch イベントdispatchせず即座にネットワークへフォールバックします。

  • レガシーネットワークスタックの一部コードは ServiceWorker との相互作用の影響を理解するため、慎重な監査が必要な場合があります。

6.8. プライバシー

ServiceWorker は新しい永続ストレージ機能(登録マップServiceWorker登録とその ServiceWorker用)、リクエスト・レスポンスリスト名前→キャッシュマップ(キャッシュ用)、スクリプトリソースマップ(スクリプト用))を導入します。不正なWebトラッキングの脅威からユーザーを守るため、これらの永続ストレージはユーザーが消去を望む場合は消去できるべきであり、既存のユーザーコントロール(全永続ストレージの一括削除等)と連携・互換すべきです。

7. 拡張性

Service Workers仕様は他の仕様から拡張可能です。

7.1. ServiceWorkerRegistrationに結びつけたAPI定義

仕様は、ServiceWorker登録に結びつけたAPIを、ServiceWorkerRegistration インターフェースへの partial interface 定義を使って、仕様固有の属性やメソッドを定義することで定義してもよいです:

partial interface ServiceWorkerRegistration {
  // 例: API名前空間の定義
  readonly attribute APISpaceType APISpace;
  // 例: メソッドの定義
  Promise<T> methodName(/* 引数リスト */);
};

7.2. 機能的イベントの定義

仕様は、ExtendableEvent インターフェースを拡張して機能的イベント定義してもよいです:

// 例: FunctionalEventインターフェース定義
interface FunctionalEvent : ExtendableEvent {
  // 機能的イベント固有の属性・メソッドを追加
};

7.3. イベントハンドラの定義

仕様は、対応する機能的イベントのイベントハンドラ属性を、ServiceWorkerGlobalScope インターフェースへの partial interface 定義で定義してもよいです:

partial interface ServiceWorkerGlobalScope {
  attribute EventHandler onfunctionalevent;
};

7.4. 機能的イベントの発火

機能的イベントServiceWorker登録active workerにdispatch要求するには、 仕様はFire Functional Event呼び出すべきです。

付録A:アルゴリズム

以下の定義は、現行標準仕様全体で使われるユーザーエージェントの内部データ構造です。

登録マップは、(順序付きマップ)であり、キーは(ストレージキーシリアライズされたscope url)、値はServiceWorker登録です。

ジョブは、ServiceWorker登録に対するregister、update、unregisterリクエストの抽象化です。

ジョブジョブタイプregisterupdateunregisterのいずれか)を持ちます。

ジョブストレージキーストレージキー)を持ちます。

ジョブscope urlURL)を持ちます。

ジョブスクリプトurlURL)を持ちます。

ジョブワーカータイプ("classic" または "module")を持ちます。

ジョブupdate via cache mode("imports"、"all"、"none")を持ちます。

ジョブclientServiceWorkerクライアント)を持ちます。初期値はnullです。

ジョブreferrerURLまたはnull)を持ちます。

ジョブジョブpromisepromise)。初期値はnullです。

ジョブ所属ジョブキュージョブキューまたはnull)。初期値はnullです。

ジョブ等価ジョブリストジョブのリスト)。初期値は空リストです。

ジョブforce bypass cache flagを持ちます。初期値は未設定です。

2つのジョブ等価とは、ジョブタイプが同じで、以下がすべて同じ場合です:

ジョブキューは、同時実行されるジョブ群を同期させるためのスレッドセーフなキューです。ジョブキュージョブitemとして含みます。ジョブキューの初期値は空です。

scope→ジョブキュー マップは、順序付きマップで、キーはシリアライズされたscope url、値はジョブキューです。

bad import script responseは、responseで、以下のいずれかの条件を満たすものです:

ジョブの作成

入力

jobTypeジョブタイプ

storage keyストレージキー

scopeURLURL

scriptURLURL

promisepromise

clientServiceWorkerクライアント

出力

jobジョブ

  1. job を新規 ジョブとする。

  2. jobジョブタイプjobType に設定する。

  3. jobストレージキーstorage key に設定する。

  4. jobscope urlscopeURL に設定する。

  5. jobscript urlscriptURL に設定する。

  6. jobジョブpromisepromise に設定する。

  7. jobclientclient に設定する。

  8. client が null でなければ、jobreferrerclient作成URL に設定する。

  9. job を返す。

ジョブのスケジュール

入力

jobジョブ

出力

なし

  1. jobQueue を null とする。

  2. jobScopejobscope urlシリアライズ済み)とする。

  3. scope→ジョブキューマップ[jobScope] が 存在しない場合、scope→ジョブキューマップ[jobScope] を新しい ジョブキュー に設定する。

  4. jobQueuescope→ジョブキューマップ[jobScope] に設定する。

  5. jobQueue が空なら:

    1. job所属ジョブキューjobQueue に設定し、jobQueuejob をenqueueする。

    2. ジョブの実行jobQueue)を呼び出す。

  6. そうでない場合:

    1. lastJobjobQueue の末尾要素とする。

    2. joblastJobと等価 かつ lastJobジョブpromise がsettleしていなければ、joblastJob等価ジョブリストに追加する。

    3. それ以外なら、job所属ジョブキューjobQueue に設定し、jobQueuejob をenqueueする。

ジョブの実行

入力

jobQueue:ジョブキュー

出力

なし

  1. アサート:jobQueue空ではない

  2. タスクをキューに入れる。以下の手順を実行:

    1. jobjobQueue の最初の item とする。

    2. jobジョブタイプregister なら、登録job)を 並行して実行する。

    3. そうでなく jobジョブタイプupdate なら、更新job)を 並行して実行する。

      注: registerジョブとupdateジョブの場合、ユーザーエージェントは、そのジョブを開始するタスクキュー投入を、ジョブを開始したドキュメントで DOMContentLoaded イベントdispatch後まで遅延します。

    4. そうでなく jobジョブタイプunregister なら、登録解除job)を 並行して実行する。

ジョブの完了

入力

jobジョブ

出力

なし

  1. jobQueuejob所属ジョブキュー に設定する。

  2. アサート:jobQueue の最初の itemjob である。

  3. dequeuejobQueue から実行する。

  4. jobQueue空でない場合は、ジョブの実行jobQueue)を呼び出す。

ジョブpromiseの解決

入力

jobジョブ

value:任意

出力

なし

  1. jobclient が null でなければ、タスクをキューに入れるjobclient責任イベントループDOM操作タスクソース を使い、以下の手順を実行:

    1. convertedValue を null とする。

    2. jobジョブタイプregister または update なら、convertedValuevalueを表すServiceWorkerRegistrationオブジェクトjobclient)を設定する。

    3. それ以外なら、convertedValuejobclientRealmvalue に設定する。

    4. jobジョブpromiseconvertedValue でresolveする。

  2. job等価ジョブリスト の各 equivalentJob について:

    1. equivalentJobclient が null なら、次のループへ。

    2. タスクをキューに入れるequivalentJobclient責任イベントループDOM操作タスクソース を使い、以下の手順を実行:

      1. convertedValue を null とする。

      2. equivalentJobジョブタイプregister または update なら、convertedValuevalueを表すServiceWorkerRegistrationオブジェクトequivalentJobclient)を設定する。

      3. それ以外なら、convertedValueequivalentJobclientRealmvalue に設定する。

      4. equivalentJobジョブpromiseconvertedValue でresolveする。

ジョブpromiseの拒否

入力

jobジョブ

errorData例外生成に必要な情報

出力

なし

  1. jobclient が null でなければ、タスクをキューに入れるjobclient責任イベントループDOM操作タスクソース を使い、jobジョブpromise新規例外exceptionerrorDatajobclientRealm)でrejectする。

  2. job等価ジョブリスト の各 equivalentJob について:

    1. equivalentJobclient が null なら、次のループへ

    2. タスクをキューに入れるequivalentJobclient責任イベントループDOM操作タスクソース を使い、equivalentJobジョブpromise新規例外exceptionerrorDataequivalentJobclientRealm)でrejectする。

登録開始

入力

scopeURLURL/失敗/null

scriptURLURL/失敗

promisepromise

clientServiceWorkerクライアント

referrerURL

workerTypeワーカータイプ

updateViaCacheupdate via cache mode

出力

なし

  1. scriptURL が失敗なら、promiseTypeError でrejectし、これらの手順を中止する。

  2. scriptURLfragment を null に設定する。

    注: ユーザーエージェントはスクリプトurlの fragment を保存しません。つまりfragmentはServiceWorkerの識別には影響しません。

  3. scriptURLscheme が "http"/"https" 以外なら、promiseTypeError でrejectし、これらの手順を中止する。

  4. scriptURLpath 内のいずれかに ASCII大文字小文字無視 "%2f" または ASCII大文字小文字無視 "%5c" が含まれるなら、promiseTypeError でrejectし、これらの手順を中止する。

  5. scopeURL が null なら、scopeURL"./"scriptURL でパースした結果に設定する。

    注: 登録のscope urlはデフォルトでServiceWorkerスクリプトの場所になります。

  6. scopeURL が失敗なら、promiseTypeError でrejectし、これらの手順を中止する。

  7. scopeURLfragment を null に設定する。

    注: ユーザーエージェントはscope urlの fragment を保存しません。つまりfragmentはServiceWorker登録の識別には影響しません。

  8. scopeURLscheme が "http"/"https" 以外なら、promiseTypeError でrejectし、これらの手順を中止する。

  9. scopeURLpath 内のいずれかに ASCII大文字小文字無視 "%2f" または ASCII大文字小文字無視 "%5c" が含まれるなら、promiseTypeError でrejectし、これらの手順を中止する。

  10. storage keyclientからストレージキー取得 の結果とする。

  11. jobCreate Job(register、storage keyscopeURLscriptURLpromiseclient)の結果とする。

  12. jobworker typeworkerType に設定する。

  13. jobupdate via cache modeupdateViaCache に設定する。

  14. jobreferrerreferrer に設定する。

  15. ジョブのスケジュールjob)を呼び出す。

登録

入力

jobジョブ

出力

なし

  1. potentially trustworthy originjobscript urlのorigin)の結果が Not Trusted なら:

    1. ジョブpromiseの拒否job、"SecurityError" DOMException)を呼び出す。

    2. ジョブの完了job)を呼び出し、これらの手順を中止する。

  2. jobscript urloriginjobreferrerorigin同一オリジンでなければ:

    1. ジョブpromiseの拒否job、"SecurityError" DOMException)を呼び出す。

    2. ジョブの完了job)を呼び出し、これらの手順を中止する。

  3. jobscope urloriginjobreferrerorigin同一オリジンでなければ:

    1. ジョブpromiseの拒否job、"SecurityError" DOMException)を呼び出す。

    2. ジョブの完了job)を呼び出し、これらの手順を中止する。

  4. registrationGet Registrationjobストレージキーjobscope url)の結果とする。

  5. registration が null でなければ:

    1. newestWorkerGet Newest Workerregistration)の結果とする。

    2. newestWorker が null でなく、jobscript urlnewestWorkerのscript urlと一致jobworker type が newestWorkerのtypeと一致、jobupdate via cache mode が registrationのupdate via cache modeと一致するなら:

      1. ジョブpromiseの解決jobregistration)を呼び出す。

      2. ジョブの完了job)を呼び出し、これらの手順を中止する。

  6. それ以外:

    1. Set Registrationjobストレージキーjobscope urljobupdate via cache mode)アルゴリズムを呼び出す。

  7. Updatejob)アルゴリズムを呼び出す。

更新

入力

jobジョブ

出力

なし

  1. registrationGet Registrationjobストレージキーjobscope url)の結果とする。

  2. registration が null なら:

    1. ジョブpromiseの拒否jobTypeError)を呼び出す。

    2. ジョブの完了job)を呼び出し、これらの手順を中止する。

  3. newestWorkerGet Newest Workerregistration)の結果とする。

  4. jobジョブタイプupdate かつ newestWorker が null でなく、かつ newestWorkerscript urljobのscript urlと一致しないなら:

    1. ジョブpromiseの拒否jobTypeError)を呼び出す。

    2. ジョブの完了job)を呼び出し、これらの手順を中止する。

  5. hasUpdatedResources を false とする。

  6. updatedResourceMap順序付きマップ(キー:URL、値:response)とする。

  7. jobworker type に応じて以下のオプションでサブステップを実行:

    "classic"

    クラシックワーカースクリプトのfetchjobシリアライズ済み script urljobclient、"serviceworker"、このServiceWorker用の生成予定environment settings object)を呼び出す。

    "module"

    モジュールワーカースクリプトグラフのfetchjobシリアライズ済み script urljobclient、"serviceworker"、"omit"、このServiceWorker用の生成予定environment settings object)を呼び出す。

    実体environment settings objectではなく生成予定objectを使う。ServiceWorker独自の処理モデルのため。他のweb workerとの違い。HTML標準のスクリプトfetchアルゴリズムは本来他のweb worker用で実行環境のsettings objectが必要だが、ServiceWorkerは後で何度もスクリプトを実行するため先にfetchする。

    HTMLのクラシック/モジュールワーカースクリプトfetchアルゴリズムはjobclientを引数に取るが、jobclientはSoft Updateアルゴリズムから呼ぶときnull。

    fetchフックrequest)の実行手順:

    1. requestheader list に `Service-Worker`/`script` を追加する。

      注: Service-Workerヘッダー定義は付録B参照。

    2. 以下のいずれかが真なら requestcache mode を "no-cache" に設定:

      注: cache modeが"no-cache"でなくても、ユーザーエージェントはネットワーク層でCache-Controlヘッダーmax-age値に従いキャッシュバイパス判断。

    3. requestservice-workers mode を "none" に設定する。

    4. isTopLevelフラグが未設定なら、fetchrequest)結果を返す。

    5. requestredirect mode を "error" に設定する。

    6. fetchrequest)を実行し、processResponseのresponse(response)で残りの手順を非同期で実行。

    7. responseheader list からMIME type抽出。このMIME type(パラメータ無視)がJavaScript MIME typeでなければ:

      1. ジョブpromiseの拒否job、"SecurityError" DOMException)を呼び出す。

      2. 非同期でネットワークエラーとして処理終了。

    8. serviceWorkerAllowedextracting header list values(`Service-Worker-Allowed`、responseheader list)の結果とする。

      注: Service-Worker-Allowedヘッダー定義は付録B参照。

    9. policyContainerfetch responseからポリシーコンテナ生成response)の結果とする。

    10. serviceWorkerAllowed が失敗なら:

      1. 非同期でネットワークエラーとして処理終了。

    11. scopeURLregistrationscope url に設定する。

    12. maxScopeString を null とする。

    13. serviceWorkerAllowed が null なら:

      1. resolvedScope"./"jobscript urlでパースした結果とする。

      2. maxScopeString を "/"+resolvedScopepath(空文字含む)を"/"区切りで連結した文字列に設定。

        注: 最後のpath要素は常に空文字なのでmaxScopeStringは末尾"/"。

    14. それ以外:

      1. maxScopeを、serviceWorkerAllowedjobスクリプトURL基準URLとして構文解析した結果とする。

      2. maxScopeoriginjobscript urlorigin と一致すれば:

        1. maxScopeString を "/"+maxScopepath(空文字含む)を"/"区切りで連結した文字列に設定。

    15. scopeString を "/"+scopeURLpath(空文字含む)を"/"区切りで連結した文字列に設定。

    16. maxScopeString が null または scopeStringmaxScopeString で始まらなければ:

      1. ジョブpromiseの拒否job、"SecurityError" DOMException)を呼び出す。

      2. 非同期でネットワークエラーとして処理終了。

    17. urlrequesturl に設定。

    18. updatedResourceMap[url] に response を設定。

    19. responsecache state が "local" でなければ、registrationlast update check time を現在時刻に設定。

    20. 以下のいずれかが真なら hasUpdatedResources をtrueに:

    21. hasUpdatedResources がfalseで newestWorkerclassic scripts imported flag が設定済みなら:

      注: メインスクリプトが変わらない場合importされたスクリプトの更新有無を確認。

      1. importUrlstoredResponse について、newestWorkerscript resource map内で:

        1. importUrlurl なら次へ。

        2. importRequest を新しいrequest(url: importUrl、client: jobclient、destination: "script"、parser metadata: "not parser-inserted"、use-URL-credentials flagセット)とする。

        3. importRequestcache mode を "no-cache" にする条件:

        4. fetchedResponsefetchimportRequest)の結果とする。

        5. updatedResourceMap[importRequesturl] に fetchedResponse を設定。

        6. fetchedResponsefetchedResponseunsafe response に設定。

        7. fetchedResponsecache state が "local" でなければ、registrationlast update check time を現在時刻に。

        8. fetchedResponsebad import script response なら次へ。

          注: importScripts() のbad responseはバイト比較対象外。詳細はissue #1374参照。

        9. fetchedResponsebodystoredResponseunsafe responsebody とバイト一致しなければ hasUpdatedResources をtrueに。

          注: この判定でループbreakしない。全import済みスクリプトをキャッシュに入れる。

    22. 非同期でresponseとして手順終了。

    アルゴリズムが非同期完了したら、残りの手順をscript(非同期完了値)で続行。

  8. script がnullまたは Is Async Modulescriptrecordscriptbase URL、« »)がtrueなら:

    1. ジョブpromiseの拒否jobTypeError)を呼び出す。

      注: 既にSecurityErrorでreject済みなら何もしない。

    2. newestWorker が null なら 登録マップ[(registrationストレージキーシリアライズ済み scopeURL)]を削除。

    3. ジョブの完了job)を呼び出し、これらの手順を中止する。

  9. hasUpdatedResources がfalseなら:

    1. registrationupdate via cache modejobupdate via cache mode に設定。

    2. ジョブpromiseの解決jobregistration)を呼び出す。

    3. ジョブの完了job)を呼び出し、これらの手順を中止する。

  10. worker を新規ServiceWorkerとする。

  11. workerscript urljobscript url に、 workerscript resourcescript に、 workertypejobworker type に、 workerscript resource mapupdatedResourceMap に設定。

  12. workerset of used scriptsurl を追加。

  13. workerscript resourcepolicy containerpolicyContainer に設定。

  14. forceBypassCachejobforce bypass cache flag が設定済みならtrue、そうでなければfalseに。

  15. runResultRun Service WorkerworkerforceBypassCache)の結果とする。

  16. runResultfailureまたはabrupt completionなら:

    1. ジョブpromiseの拒否jobTypeError)を呼び出す。

    2. newestWorker が null なら 登録マップ[(registrationストレージキーシリアライズ済み scopeURL)]を削除。

    3. ジョブの完了job)を呼び出す。

  17. それ以外の場合、Installjobworkerregistration)アルゴリズムを呼び出す。

ソフトアップデート

ユーザーエージェントは好きな頻度で呼び出してアップデートを確認してもよい

入力

registrationServiceWorker登録

forceBypassCache:オプションのboolean。デフォルトはfalse。

注: 実装者はforceBypassCacheをデバッグ用途(開発者ツールなど)や、ServiceWorker拡張仕様で任意に利用してもよい

出力

なし

  1. newestWorkerGet Newest Workerregistration)の結果とする。

  2. newestWorker が null なら、これらの手順を中止する。

  3. jobCreate Job(update、registrationストレージキーregistrationscope urlnewestWorkerscript url、null、null)で生成。

  4. jobworker typenewestWorkertype に設定する。

  5. forceBypassCache が true なら jobforce bypass cache flag を設定する。

  6. ジョブのスケジュールjob)を呼び出す。

インストール

入力

jobジョブ

workerServiceWorker

registrationServiceWorker登録

出力

なし

  1. installFailed を false とする。

  2. newestWorkerGet Newest Workerregistration)の結果とする。

  3. registrationupdate via cache modejobupdate via cache mode に設定する。

  4. Update Registration Stateregistration、"installing"、worker)を呼び出す。

  5. Update Worker Stateregistrationinstalling worker、"installing")を呼び出す。

  6. アサート:jobジョブpromise はnullではない。

  7. ジョブpromiseの解決jobregistration)を呼び出す。

  8. settingsObjectsenvironment settings object のうち originregistrationscope urlorigin であるもの全てとする。

  9. settingsObjects の各 settingsObject について、タスクをキューに入れるsettingsObject責任イベントループDOM操作タスクソース)で以下を実行:

    1. registrationObjectssettingsObjectrealmにある ServiceWorkerRegistration オブジェクトのうち service worker registrationregistration であるもの全てとする。

    2. registrationObjects の各 registrationObject について updatefoundイベント発火registrationObject)。

  10. installingWorkerregistrationinstalling worker に設定。

  11. Should Skip EventinstallingWorker、"install")の結果がfalseなら:

    1. jobforce bypass cache flag が設定済みなら forceBypassCache を true、そうでなければ false。

    2. Run Service WorkerinstallingWorkerforceBypassCache)が失敗なら:

      1. installFailed を true に。

    3. そうでなければ:

      1. タスクtaskをキューに入れるinstallingWorkerevent loopDOM操作タスクソース)で以下を実行:

        1. eInstallEventイベント生成結果とする。

        2. etypeinstall に初期化。

        3. DispatcheinstallingWorkerグローバルオブジェクト)。

        4. WaitForAsynchronousExtensions: 以下のサブステップを 並行して実行:

          1. eactive でなくなるまで待つ。

          2. etimed out flag がセットされたら installFailed を true に。

          3. pextend lifetime promises全て待つpromiseeextend lifetime promises)の結果とする。

          4. pがrejectされたら installFailed を true に。

        task が破棄されたら installFailed を true に。

      2. task が実行または破棄されるまで待つ。

      3. WaitForAsynchronousExtensionsラベルのステップが完了するまで待つ。

  12. installFailed が true なら:

    1. Update Worker Stateregistrationinstalling worker、"redundant")を実行。

    2. Update Registration Stateregistration、"installing"、null)を実行。

    3. newestWorker が null なら 登録マップ[(registrationストレージキーシリアライズ済み registrationscope url)]を削除。

    4. ジョブの完了job)を呼び出し、これらの手順を中止する。

  13. mapregistrationinstalling workerscript resource map に設定。

  14. usedSetregistrationinstalling workerset of used scripts に設定。

  15. url について map 内で:

    1. usedSeturl含まないなら map[url] を削除。

  16. registrationwaiting worker が null でなければ:

    1. Terminateregistrationwaiting worker)。

    2. Update Worker Stateregistrationwaiting worker、"redundant")を実行。

  17. Update Registration Stateregistration、"waiting"、registrationinstalling worker)を実行。

  18. Update Registration Stateregistration、"installing"、null)を実行。

  19. Update Worker Stateregistrationwaiting worker、"installed")を実行。

  20. ジョブの完了job)を呼び出す。

  21. このアルゴリズムで タスクキューされた Update Worker Statetask がすべて実行完了するまで待つ。

  22. Try Activateregistration)を呼び出す。

    注: Try ActivateActivate が発火しなかった場合は、既存のactive workerを制御する最後のクライアントがアンロードされたり、skipWaiting()が非同期で呼び出された場合、または既存active workerextend lifetime promisesがsettleした場合に再度Activateが試行される。

アクティベート

入力

registrationServiceWorker登録

出力

なし

  1. registrationwaiting worker が null なら、これらの手順を中止する。

  2. registrationactive worker が null でなければ:

    1. Terminateregistrationactive worker)。

    2. Update Worker Stateregistrationactive worker、"redundant")を実行。

  3. Update Registration Stateregistration、"active"、registrationwaiting worker)を実行。

  4. Update Registration Stateregistration、"waiting"、null)を実行。

  5. Update Worker Stateregistrationactive worker、"activating")を実行。

    注: active workerがactivating中は、ランタイムスクリプトエラーや強制終了があってもactive workerのアクティベートは妨げられない。

    注: アクティベートハンドラは非本質的な作業(クリーンアップなど)を行うよう設計すること。ブラウザ終了等で完了しないこともあり得るので、ServiceWorkerはアクティベートハンドラが完了しなくても正常動作するよう設計すべき。

  6. matchedClientsリストServiceWorkerクライアントで、creation URLregistrationストレージキーおよびregistrationscope urlと一致するもの)とする。

  7. client について matchedClients内で、タスクをキューに入れるclient責任イベントループDOM操作タスクソース)で以下を実行:

    1. readyPromiseclientglobal objectServiceWorkerContainerready promise とする。

    2. readyPromise が null なら次へ。

    3. readyPromiseがpendingなら、registrationを表すServiceWorkerRegistrationオブジェクト(readyPromiserelevant settings objectで)でresolve。

  8. ServiceWorkerクライアント clientregistrationuseしているもの)について:

    1. clientactive workerregistrationactive worker に設定。

    2. Notify Controller Changeclient)アルゴリズムを呼び出す。

  9. activeWorkerregistrationactive worker に設定。

  10. Should Skip EventactiveWorker、"activate")の結果がfalseなら:

    1. Run Service WorkeractiveWorker)の結果が失敗でなければ:

      1. タスクtaskをキューに入れるactiveWorkerevent loopDOM操作タスクソース)で以下を実行:

        1. eExtendableEventイベント生成結果とする。

        2. etypeactivate に初期化。

        3. DispatcheactiveWorkerグローバルオブジェクト)。

        4. WaitForAsynchronousExtensions: 並行して eactive でなくなるまで待つ。

      2. task が実行または破棄されるまで待つ。

      3. WaitForAsynchronousExtensionsラベルのステップが完了するまで待つ。

  11. Update Worker Stateregistrationactive worker、"activated")を実行。

アクティベート試行

入力

registrationServiceWorker登録

出力

なし

  1. registrationwaiting worker が null なら return。

  2. registrationactive worker が null でなく、かつ registrationactive workerstate が "activating" なら return。

    注: 既存active workerがまだactivating状態なら、waiting workerのアクティベートは遅延される。

  3. 以下のいずれかが真なら Activateregistration)を呼び出す:

ServiceWorkerGlobalScopeのセットアップ

入力

serviceWorkerServiceWorker

出力

ServiceWorkerGlobalScope オブジェクトまたはnull

注: このアルゴリズムはCSPチェック等で使えるServiceWorkerGlobalScope またはnullを返す。serviceWorkerがactiveなServiceWorkerGlobalScopeを持つ場合はそれを返し、そうでなければ新規生成。

このアルゴリズムはServiceWorkerのCSP/COEP等セキュリティチェックに必要な最小限のセットアップのみ行う。このアルゴリズムは全てのセキュリティチェック前に確実に呼び出されることを仕様で保証する。

仕様上、こうしたセキュリティチェックにはServiceWorkerGlobalScoperelevant settings objectrealmagent生成が必要。実装ではこのアルゴリズムで必要最低限の作業だけ行い、Run Service Workerで残りを実行しても良い(結果が観測可能に等価ならOK。特に全セキュリティチェック結果が同じならOK)。

  1. unsafeCreationTimeunsafe shared current time に設定。

  2. serviceWorkerrunning なら serviceWorkerglobal object を返す。

  3. serviceWorkerstate が "redundant" なら null を返す。

  4. serviceWorkerglobal object が nullでなければ serviceWorkerglobal object を返す。

  5. アサート:serviceWorkerstart status は null。

  6. setupFailed を false とする。

  7. globalObject を null とする。

  8. agentservice worker agent取得の結果とし、そのコンテキストで以下を実行:

    1. realmExecutionContext新規realm生成agent+以下カスタマイズ)結果とする:

      • グローバルオブジェクトとして新しいServiceWorkerGlobalScope オブジェクトを生成。workerGlobalScopeはこのオブジェクト。

    2. settingsObject を新規environment settings object(以下のアルゴリズム定義):

      realm execution context

      realmExecutionContext を返す。

      module map

      workerGlobalScopemodule map を返す。

      API base URL

      serviceWorkerscript url を返す。

      origin

      登録元 ServiceWorkerクライアントorigin を返す。

      policy container

      workerGlobalScopepolicy container を返す。

      time origin

      coarseningunsafeCreationTimeworkerGlobalScopecross-origin isolated capability)の結果を返す。

    3. settingsObjectidを新規一意な不透明文字列、creation URLserviceWorkerscript urltop-level creation URLをnull、top-level origin実装依存値、target browsing contextをnull、active service workerをnullに設定。

    4. workerGlobalScopeurlserviceWorkerscript url に設定。

    5. workerGlobalScopepolicy containerserviceWorkerscript resourcepolicy container に設定。

    6. workerGlobalScopetypeserviceWorkertype に設定。

    7. 新規WorkerLocationオブジェクトを生成し、workerGlobalScopeに関連付ける。

    8. CSP初期化workerGlobalScope)の結果が"Blocked"なら setupFailed を true にして手順中止。

    9. globalObjectworkerGlobalScope に設定。

  9. globalObject が null でなくなるか setupFailed が true になるまで待つ。

  10. setupFailed が true なら null を返す。

  11. globalObject を返す。

ServiceWorkerの実行

入力

serviceWorkerServiceWorker

forceBypassCache:オプションのboolean。デフォルトはfalse

出力

Completionまたは失敗

注: このアルゴリズムはServiceWorkerがrunning状態になるか起動失敗するまでブロックする。

  1. serviceWorkerrunning なら、serviceWorkerstart status を返す。

  2. serviceWorkerstate が "redundant" なら 失敗 を返す。

  3. アサート:serviceWorkerstart status は null。

  4. scriptserviceWorkerscript resource に設定。

  5. アサート:script は null でない。

  6. startFailed を false とする。

  7. workerGlobalScopeserviceWorkerglobal object に設定。

  8. workerGlobalScope が null なら:

    1. workerGlobalScopeServiceWorkerGlobalScopeのセットアップserviceWorker)の結果に設定。

    2. workerGlobalScope が null なら 失敗 を返す。

    3. serviceWorkerglobal objectworkerGlobalScope に設定。

  9. workerGlobalScoperealm execution context用エージェント取得し、そのコンテキストで以下を実行:

    1. forceBypassCache が true なら workerGlobalScopeimportScripts用キャッシュバイパスフラグ を設定。

    2. serviceWorkeractive worker かつ serviceWorker登録task queues にタスクがあれば、それらをserviceWorkerevent looptask queuesに元のtask source順でキューに入れる。

    3. evaluationStatus を null とする。

    4. scriptクラシックスクリプトなら:

      1. evaluationStatusクラシックスクリプトの実行script)の結果に設定。

      2. evaluationStatus.[[Value]]が空なら(スクリプト未評価)、startFailed を true にし手順中止。

    5. それ以外で scriptモジュールスクリプトなら:

      1. evaluationPromiseモジュールスクリプトの実行script、report errors: false)の結果に設定。

      2. アサート:evaluationPromise.[[PromiseState]] は "pending" でない。

      3. evaluationPromise.[[PromiseState]] が "rejected" なら:

        1. evaluationStatusThrowCompletion(evaluationPromise.[[PromiseResult]])に設定。

      4. それ以外なら:

        1. evaluationStatusNormalCompletion(undefined)に設定。

    6. スクリプトがTerminate Service Workerアルゴリズムで中断されたら、startFailed を true にし手順中止。

    7. serviceWorkerstart statusevaluationStatus に設定。

    8. scripthas ever been evaluated flag が未設定なら:

      1. settingsObjectglobal object の関連付けられたevent listenersのevent typeごとに:

        1. eventTypeworkerGlobalScope の関連service workerset of event types to handleに追加。

        注: この時点でevent listenerがなければ、service workerのset of event types to handleは空集合。

      2. scripthas ever been evaluated flag をセット。

      3. serviceWorkerall fetch listeners are empty flag を未設定に。

      4. ユーザーエージェントは、All Fetch Listeners Are EmptyworkerGlobalScope)がtrueならserviceWorkerall fetch listeners are empty flag を設定してもよい

    9. responsible event loopsettingsObject指定)を破棄されるまで実行。

    10. ClearworkerGlobalScopemap of active timers)。

  10. serviceWorkerrunning になるか startFailed がtrueになるまで待つ。

  11. startFailed がtrueなら 失敗 を返す。

  12. serviceWorkerstart status を返す。

fetchリスナーが全て空である

入力

workerGlobalScopeglobal object

出力

boolean

  1. workerGlobalScopeset of event types to handlefetch を含まなければ true を返す。

  2. eventHandlerworkerGlobalScopeevent handler map["onfetch"]の値に設定。

  3. eventListenerCallbackslegacy-obtain service worker fetch event listener callbacksworkerGlobalScope)の結果に設定。

  4. eventListenerCallback について eventListenerCallbacks内で:

    1. callback を null とする。

    2. eventHandler が null でなく eventListenerCallbackeventHandlerlistenercallback と等しいなら、callbackIDL値→ECMAScript値変換eventHandlervalue)結果に設定。

    3. それ以外なら callbackIDL値→ECMAScript値変換eventListenerCallback)結果に設定。

    4. IsCallablecallback)がfalseなら false を返す。

      注: Callback オブジェクトが handleEvent(event) を使う場合は空でないと判断。getter呼び出しでevent listener変更されるのを避けるため。

    5. callbackfunction body が空でなければ(statementまたはdeclarationがあれば) false を返す。

    注: () => {} のようなfetchリスナーを検出。一部サイトはPWA認定目的で空bodyのfetchリスナーを持つ。

  5. true を返す。

注: ユーザーエージェントは空fetchリスナーが不要で性能低下の可能性ある旨警告表示を推奨。

ServiceWorkerの終了

入力

serviceWorkerServiceWorker

出力

なし

  1. serviceWorker のメインループと並行して以下を実行:

    1. serviceWorkerGlobalScopeserviceWorkerglobal object に設定。

    2. serviceWorkerGlobalScopeclosing フラグをtrueに。

    3. serviceWorkerset of extended events から全itemを削除

    4. serviceWorkerGlobalScopeevent looptask queues に「handle fetch task source」か「handle functional event task source」のtask sourceを持つタスクがあれば、それらをserviceWorker登録の対応する task queues に元のtask source順でキューに入れ、他のタスク(messageイベント等)は全て破棄する。

      注: fetchイベントやpush等他の機能的イベントはregistrationのtask queuesに退避され、他のtask(message等)は破棄される。

    5. 実行中スクリプトの中断serviceWorker)。

    6. serviceWorkerstart status を null に。

Fetch処理

Fetch処理アルゴリズムはfetch処理をServiceWorkerコンテキストへ委譲するエントリポイントです。

入力

requestrequest

fetchControllerfetch controller

useHighResPerformanceTimers:boolean

出力

response

  1. registration を null とする。

  2. clientrequestclientに設定。

  3. reservedClientrequestreserved clientに設定。

  4. preloadResponse を新規promiseに設定。

  5. workerRealm を null とする。

  6. timingInfo を新規service worker timing infoに設定。

  7. アサート:requestdestination は "serviceworker" でない。

  8. requestdestination が "embed" または "object" なら:

    1. null を返す。

  9. それ以外で request非サブリソースリクエストなら:

    1. reservedClient が null でなく environment settings objectなら:

      1. reservedClientsecure context でなければ null を返す。

    2. それ以外:

      1. requesturl潜在的に信頼できるURLでなければ null を返す。

    3. requestナビゲーションリクエストで、navigateがshift+reload等で起動された場合は null を返す。

    4. AssertreservedClient は null でない。

    5. storage keyストレージキー取得reservedClient)の結果に設定。

    6. registrationMatch Service Worker Registrationstorage keyrequesturl)の結果に設定。

    7. registrationが null または registrationactive workerが null なら null を返す。

    8. requestdestination"report" でなければ、reservedClientactive service workerregistrationactive workerに設定。

    注: この時点からServiceWorkerクライアントは自身のactive service workerServiceWorker登録useし始めます。

  10. それ以外で requestサブリソースリクエストなら:

    1. clientactive service worker が非nullなら、registrationclientactive service workerServiceWorker登録に設定。

    2. それ以外は null を返す。

  11. activeWorkerregistrationactive workerに設定。

  12. 以下いずれかが真なら shouldSoftUpdate を true、そうでなければ false に:

  13. activeWorkerrouterルールリストが空でなければ:

    1. sourceGet Router Sourceregistrationactive workerrequest)の結果に設定。

    2. source"network"なら:

      1. shouldSoftUpdate が true なら 並行してSoft Updateregistration)を実行。

      2. null を返す。

    3. それ以外で source"cache" または source["cacheName"]が存在するなら:

      1. shouldSoftUpdate が true なら 並行してSoft Updateregistration)を実行。

      2. cacheNamecache について registrationストレージキーname to cache map から:

        1. source["cacheName"]が存在しかつcacheNameと一致しなければスキップ。

        2. requestResponsesQuery Cacherequest、新規CacheQueryOptionscache)の結果に設定。

        3. requestResponses が空リストなら null を返す。

        4. それ以外:

          1. requestResponserequestResponses の先頭要素に設定。

          2. responserequestResponse の response に設定。

          3. globalObjectactiveWorkerglobal objectに設定。

          4. globalObject が null なら:

            1. globalObjectServiceWorkerGlobalScopeのセットアップactiveWorker)の結果に設定。

          5. globalObject が null なら null を返す。

          注: CORSチェックのためServiceWorkerGlobalScopeを生成するだけであり、実装で実際に生成するとは限らない。

          1. responsetype が "opaque"かつcross-origin resource policy checkglobalObjectoriginglobalObject、""、responseinternal response)がblockedなら null を返す。

          2. response を返す。

      3. null を返す。

    4. それ以外で source"race-network-and-fetch-handler" かつ requestmethod が `GET` なら:

      1. shouldSoftUpdate が true なら 並行してSoft Updateregistration)を実行。

      2. queue を空のqueueresponse用)に設定。

      3. raceFetchController を null に設定。

      4. raceResponserace responsevalueが "pending")に設定。

      5. 以下のサブステップを並行して、かつfetchControllerstateが"terminated"または"aborted"なら中断:

        1. raceFetchControllerfetchrequest、processResponse: 以下の手順)結果に設定:

          1. raceNetworkRequestResponsestatusok status なら:

            1. raceResponsevalueraceNetworkRequestResponseに設定。

            2. queueraceNetworkRequestResponseをenqueue。

          2. それ以外は raceResponsevaluenetwork errorに設定。

      6. 中断時raceFetchControllerがnullでなければ:

        1. AbortraceFetchController)。

        2. raceResponserace responsevalueがnull)に設定。

      7. preloadResponse を undefined でresolve。

      8. 以下のサブステップを並行して実行:

        1. fetchHandlerResponseCreate Fetch Event and DispatchrequestregistrationuseHighResPerformanceTimerstimingInfoworkerRealmreservedClientpreloadResponseraceResponse)の結果に設定。

        2. fetchHandlerResponse が null でもなく network error でもなく、かつ raceFetchControllerがnullでなければ AbortraceFetchController)。

        3. queuefetchHandlerResponseをenqueue。

      9. queueが空でなくなるまで待つ。

      10. dequeuequeue)の結果を返す。

    5. アサート:sourceは"fetch-event"である。

  14. requestnavigation requestで、 registrationnavigation preload enabled flagがセットされ、 requestmethodが`GET`で、 registrationactive workerset of event types to handlefetchを含み、 registrationactive workerall fetch listeners are empty flagが未設定なら:

    注: 上記でregistrationactive workerset of event types to handlefetchを含まない場合は、コンソール警告表示推奨(開発者意図不明のため)。

    1. preloadRequestrequest複製request)の結果に設定。

    2. preloadRequestHeaderspreloadRequestheader listに設定。

    3. preloadResponseObject を新規Response(新規Headers、guard: "immutable")に設定。

    4. header追加preloadRequestHeaders、name: `Service-Worker-Navigation-Preload`、value: registrationnavigation preload header value)。

    5. preloadRequestservice-workers mode を "none" に設定。

    6. preloadFetchController を null に設定。

    7. 以下のサブステップを並行してfetchControllerstate が"terminated"または"aborted"なら中断:

      1. preloadFetchControllerfetchpreloadRequest)結果に設定。

        processResponse(navigationPreloadResponse)で以下を実行:

        1. navigationPreloadResponsetype が"error"なら preloadResponseTypeErrorでrejectし手順終了。

        2. preloadResponseObjectnavigationPreloadResponseを関連付け。

        3. preloadResponsepreloadResponseObjectでresolve。

    8. 中断時

      1. deserializedErrordeserialize a serialized abort reason(null、workerRealm)の結果に設定。

      2. AbortpreloadFetchControllerdeserializedError)。

  15. それ以外は preloadResponse を undefined でresolve。

  16. Create Fetch Event and DispatchrequestregistrationuseHighResPerformanceTimerstimingInfoworkerRealmreservedClientpreloadResponse、null)の結果を返す。

Fetchイベント生成・dispatch

入力

requestrequest

registrationServiceWorker登録

useHighResPerformanceTimers:boolean

timingInfoServiceWorker timing info

workerRealmグローバルオブジェクトのrelevant realm

reservedClientreserved client

preloadResponsepromise

raceResponserace responseまたはnull

出力

response

  1. response を null とする。

  2. eventCanceled を false とする。

  3. clientrequestclientに設定。

  4. activeWorkerregistrationactive workerに設定。

  5. eventHandled を null とする。

  6. handleFetchFailed を false とする。

  7. respondWithEntered を false とする。

  8. 以下いずれかが真なら shouldSoftUpdate を true、そうでなければ false に:

  9. Should Skip Event("fetch"、activeWorker)がtrueなら:

    1. shouldSoftUpdate が true なら 並行して Soft Updateregistration)を実行。

    2. null を返す。

  10. activeWorkerall fetch listeners are empty flag がセットされていれば:

    1. 並行して

      1. activeWorkerstate が "activating" なら、activeWorkerstate が "activated" になるまで待つ。

      2. ServiceWorkerの実行activeWorker)を実行。

      3. shouldSoftUpdate が true なら Soft Updateregistration)を実行。

    2. null を返す。

  11. useHighResPerformanceTimers が true なら useHighResPerformanceTimersactiveWorkerglobal objectcross-origin isolated capabilityに設定。

  12. timingInfostart timecoarsened shared current timeuseHighResPerformanceTimers)に設定。

  13. activeWorkerstate が "activating"なら activeWorkerstate が "activated"になるまで待つ。

  14. ServiceWorkerの実行activeWorker)の結果が失敗なら handleFetchFailed を true に。

  15. それ以外:

    1. workerRealmactiveWorkerglobal objectrelevant realmに設定。

    2. eventHandled新規promiseworkerRealm)に設定。

    3. raceResponse が null でなければ、setactiveWorkerglobal objectrace response map[request] = raceResponse)。

    4. タスクtaskをキューに入れる(以下のサブステップを実行):

      1. eFetchEventイベント生成結果に設定。

      2. abortController を新規AbortControllerworkerRealm)に設定。

      3. requestObjectRequestオブジェクト生成request、新規Headers(guard: "immutable")、abortControllersignalworkerRealm)結果に設定。

      4. etypefetchに初期化。

      5. ecancelable を true に初期化。

      6. erequestrequestObject に初期化。

      7. epreloadResponsepreloadResponse に初期化。

      8. eclientIdclientid に初期化。

      9. request非サブリソースリクエストかつ requestdestination"report"でなければ、eresultingClientIdreservedClientid、それ以外は空文字列に初期化。

      10. requestナビゲーションリクエストなら ereplacesClientIdrequestreplaces client id、それ以外は空文字列に初期化。

      11. ehandledeventHandled に初期化。

      12. timingInfofetch event dispatch timecoarsened shared current timeuseHighResPerformanceTimers)に設定。

      13. DispatcheactiveWorkerglobal object)。

      14. Update Service Worker Extended Events SetactiveWorkere)を呼び出す。

      15. erespond-with entered flag がセットされていれば respondWithEntered を true に。

      16. ewait to respond flag がセットされていれば:

        1. ewait to respond flag が解除されるまで待つ。

        2. erespond-with error flag がセットされていれば handleFetchFailed を true に。

        3. それ以外は responseepotential responseに設定。

      17. response が null かつ requestbody が nullでなく、かつ requestbodysource が nullなら:

        1. requestbodyunusableなら handleFetchFailed を true に。

        2. それ以外は cancelrequestbody、undefined)。

      18. response が nullでなければ responseservice worker timing infotimingInfoに設定。

      19. ecanceled flag がセットされていれば eventCanceled を true に。

      20. fetchControllerstate が"terminated"または"aborted"なら:

        1. deserializedErrordeserialize a serialized abort reasonfetchControllerserialized abort reasonworkerRealm)に設定。

        2. タスクをキューに入れるsignal abortabortControllerdeserializedError))。

      task が破棄されたら handleFetchFailed を true に。

      taskactiveWorkerevent loopおよび handle fetch task source必ず使うこと。

  16. task が実行されるか handleFetchFailed が true になるまで待つ。

  17. shouldSoftUpdate が true なら 並行してSoft Updateregistration)を実行。

  18. activeWorkerglobal objectrace response map[request]が存在するなら、race response map[request]を削除。

  19. respondWithEntered が false なら:

    1. eventCanceled が true なら:

      1. eventHandled が nullでなければ rejecteventHandled、"NetworkError" DOMExceptionworkerRealm)。

      2. network errorを返す。

    2. eventHandled が nullでなければ resolveeventHandled)。

    3. raceResponsevalue が nullでなければ:

      1. raceResponsevalue が "pending" でなくなるまで待つ。

      2. raceResponsevalueresponseなら、raceResponsevalueを返す。

    4. null を返す。

  20. handleFetchFailed が true なら:

    1. eventHandled が nullでなければ rejecteventHandled、"NetworkError" DOMExceptionworkerRealm)。

    2. network errorを返す。

  21. eventHandled が nullでなければ resolveeventHandled)。

  22. response を返す。

URLパターンの解析

入力

rawPatternURLPatternCompatible

serviceWorkerサービスワーカー

出力

URLパターン

  1. baseURLserviceWorkerスクリプトURLとする。

  2. rawPatternおよびbaseURLを与えて、Web IDL値からURLパターンを構築する結果を返す。

ルーター条件の検証

入力

conditionRouterCondition

serviceWorkerサービスワーカー

出力

真偽値

  1. hasConditionをfalseにする。

  2. condition["urlPattern"] が存在する場合:

    1. rawPatterncondition["urlPattern"]とする。

    2. rawPatternserviceWorkerを渡してURLパターンの解析アルゴリズムを実行した結果をpatternとする。これが例外を投げた場合はcatchし、falseを返す。

    3. pattern正規表現グループを持つ場合、falseを返す。

      注:ユーザー定義正規表現の実行はセキュリティ上の懸念があるため、禁止されている。

    4. hasConditionをtrueにする。

  3. condition["requestMethod"] が存在する場合:

    1. methodcondition["requestMethod"]とする。

    2. methodメソッドでなければ、falseを返す。

    3. method禁止メソッドならば、falseを返す。

    4. hasConditionをtrueにする。

  4. condition["requestMode"] が存在する場合、hasConditionをtrueにする。

  5. condition["requestDestination"] が存在する場合、hasConditionをtrueにする。

  6. condition["runningStatus"] が存在する場合、hasConditionをtrueにする。

  7. condition["_or"] が存在する場合:

    1. hasConditionがtrueなら、falseを返す。

      注:ルーター規則の理解を容易にするため、"or"条件は他の条件と相互排他である。

    2. orConditionscondition["_or"]とする。

    3. orConditionsの各orConditionについて:

      1. orConditionserviceWorkerを使ってルーター条件の検証アルゴリズムを実行し、falseならfalseを返す。

    4. hasConditionをtrueにする。

  8. condition["not"] が存在する場合:

    1. hasConditionがtrueなら、falseを返す。

      注:ルーター規則の理解を容易にするため、"not"条件は他の条件と相互排他である。

    2. condition["not"]とserviceWorkerを使ってルーター条件の検証アルゴリズムを実行し、falseならfalseを返す。

    3. hasConditionをtrueにする。

  9. hasConditionを返す。

ルーター条件のマッチング

入力

conditionRouterCondition

serviceWorkerサービスワーカー

requestリクエスト

出力

真偽値

注:複数の条件(例:urlPatternrunningStatusrequestMethodが設定されている場合)は、すべての条件が一致した場合にtrueが返される。

  1. condition["or"] が存在する場合:

    1. orConditionscondition["or"]とする。

    2. orConditionsの各orConditionについて:

      1. orConditionserviceWorkerrequestを使ってルーター条件のマッチングアルゴリズムを実行し、trueが返った場合はtrueを返す。

    3. falseを返す。

  2. condition["not"] が存在する場合:

    1. condition["not"]、serviceWorkerrequestを使ってルーター条件のマッチングアルゴリズムを実行し、trueが返った場合はfalseを返す。

    2. trueを返す。

  3. それ以外:

    注:ルーター条件の検証アルゴリズムは、ornotと他の条件が排他されていることを保証する。

    1. condition["urlPattern"] が存在する場合:

      1. rawPatterncondition["urlPattern"]とする。

      2. rawPatternserviceWorkerを渡してURLパターンの解析アルゴリズムを実行した結果をpatternとする。

      3. patternrequestURLマッチングを実行し、結果がnullならfalseを返す。

    2. condition["requestMethod"] が存在する場合:

      1. methodcondition["requestMethod"]とする。

      2. method正規化する。

      3. requestメソッドmethodでなければ、falseを返す。

    3. condition["requestMode"] が存在する場合:

      1. modecondition["requestMode"]とする。

      2. requestモードmodeでなければ、falseを返す。

    4. condition["requestDestination"] が存在する場合:

      1. destinationcondition["requestDestination"]とする。

      2. request宛先destinationでなければ、falseを返す。

    5. condition["runningStatus"] が存在する場合:

      1. runningStatuscondition["runningStatus"]とする。

      2. runningStatus"running"であり、serviceWorker稼働中でなければ、falseを返す。

      3. runningStatus"not-running"であり、serviceWorker稼働中ならば、falseを返す。

    6. trueを返す。

ルーター登録制限の確認

入力

routerRulesルーター規則のリスト

出力

真偽値

注: ルーター条件は_ornotを用いて複雑かつネスト可能です。過度な処理を防ぐため、このアルゴリズムでは2つの制限を設けます。第一に、すべてのネストされた条件を含む合計条件数は1024を超えてはなりません。第二に、ネストの深さは10レベルまでに制限され、指数的計算を回避します。

  1. resultルーター条件カウント結果とする。

  2. result条件数を1024に設定する。

  3. resultクォータ超過をfalseに設定する。

  4. rulerouterRulesから取り出して:

    1. resultを、Count Router Inner Conditionsアルゴリズムの rule["condition"], result、10を渡した結果で更新する。

    2. resultクォータ超過がtrueなら、falseを返す。

  5. trueを返す。

ルーター内条件数のカウント

入力

conditionRouterCondition

resultルーター条件カウント結果

depth、数値

出力

resultルーター条件カウント結果

  1. result条件数を1減らす。

  2. result条件数が0、またはdepthが0なら:

    1. resultクォータ超過をtrueに設定する。

    2. resultを返す。

  3. condition["_or"] が存在する場合:

    1. depthを1減らす。

    2. condition["_or"]の各orConditionについて:

      1. resultを、ルーター内条件数のカウントorConditionresultdepthで実行した結果で更新する。

      2. resultクォータ超過がtrueなら、resultを返す。

  4. それ以外でcondition["not"] が存在する場合:

    1. depthを1減らす。

    2. resultを、ルーター内条件数のカウントcondition["not"]、resultdepthで実行した結果で更新する。

    3. resultクォータ超過がtrueなら、resultを返す。

  5. resultを返す。

ルーターソースの取得

入力

serviceWorkerサービスワーカー

requestリクエスト

出力

RouterSource またはnull

  1. ruleserviceWorkerルーター規則のリストから取り出して:

    1. rule["condition"]、serviceWorkerrequestを使ってルーター条件のマッチングアルゴリズムを実行し、trueなら rule["source"]を返す。

  2. nullを返す。

イベントをスキップすべきか

入力

eventName、文字列

serviceWorkerサービスワーカー

出力

真偽値

注: 不要な遅延を避けるため、この仕様ではサービスワーカーのグローバルにイベントリスナーが初回スクリプト実行時に決定的に追加されていない場合、イベントのdispatchをスキップすることを許可します。

  1. serviceWorker処理するイベント型の集合eventName含まない場合、ユーザーエージェントはスキップ可能としてtrueを返すことができる。

  2. falseを返す。

機能イベントの発火

入力

eventName、文字列

eventConstructorExtendableEventを拡張したイベントコンストラクター

registrationサービスワーカー登録

initializationeventのためのeventConstructorで構築したプロパティ初期化(オプション)

postDispatchStepsアクティブワーカーのイベントループで、dispatchedEventeventConstructorでdispatchされたインスタンスをセットして実行する追加ステップ(オプション)

出力

なし

  1. アサート: registrationアクティブワーカーはnullでない。

  2. activeWorkerregistrationアクティブワーカーとする。

  3. eventNameactiveWorkerを使ってイベントをスキップすべきかを実行し、trueなら:

    1. registration古いなら、並行してソフトアップデートアルゴリズムをregistrationに対して実行する。

    2. 終了。

  4. activeWorker状態が"activating"なら、activeWorker状態が"activated"になるまで待つ。

  5. サービスワーカーの実行アルゴリズムをactiveWorkerで実行し、失敗なら:

    1. registration古いなら、並行してソフトアップデートアルゴリズムをregistrationに対して実行する。

    2. 終了。

  6. タスクtaskをキューイングして以下のサブステップを実行:

    1. eventイベント作成eventConstructoractiveWorker関連レルムを用いて生成する。

    2. initializationがnullでなければ、eventinitializationで初期化する。

    3. dispatcheventactiveWorkerグローバルオブジェクトに対して実行する。

    4. サービスワーカー拡張イベント集合の更新activeWorkereventで実行する。

    5. postDispatchStepsがnullでなければ、eventdispatchedEventとして渡してpostDispatchStepsを実行する。

    taskactiveWorkerイベントループ機能イベントタスクソースを利用する必要がある

  7. taskが実行または破棄されるのを待つ。

  8. registration古いなら、並行してソフトアップデートアルゴリズムをregistrationに対して実行する。

"amazingthing"イベント(型はAmazingThingEvent)をあるserviceWorkerRegistration上で発火し、イベントオブジェクトのプロパティを初期化する場合、次のように記述する:
  1. 機能イベントの発火 "amazingthing" を AmazingThingEvent を使い serviceWorkerRegistration 上で以下のプロパティで行う:

    propertyName

    value

    anotherPropertyName

    anotherValue

    次にdispatchedEventで以下のステップを実行:

    1. サービスワーカーのイベントループ上でdispatchedEventを必要な処理に利用する。

初期化ステップやdispatch後のステップが不要な場合の記述例:

  1. 機能イベントの発火 "whatever" を ExtendableEvent を使い serviceWorkerRegistration 上で行う。

サービスワーカークライアントのアンロード処理

ユーザーエージェントは、サービスワーカークライアントドキュメントのアンロードクリーンアップ手順または終了によりアンロードされる際、次の手順を必ず実行しなければならない。

入力

clientサービスワーカークライアント

出力

なし

  1. 以下の手順をアトミックに実施する。

  2. registrationclient利用しているサービスワーカー登録とする。

  3. registrationがnullの場合、これらの手順を中止する。

  4. 他のサービスワーカークライアントregistration利用している場合、これらの手順を中止する。

  5. registration登録解除済みの場合、登録クリア試行registrationで呼び出す。

  6. アクティベート試行registrationで呼び出す。

ユーザーエージェントのシャットダウン処理

入力

なし

出力

なし

  1. registration登録マップから取り出して:

    1. registrationインストール中ワーカーがnullでなければ:

      1. registration待機中ワーカーがnullかつregistrationアクティブワーカーがnullの場合、登録クリアregistrationで呼び出し、次の繰り返しへ進む。

      2. それ以外の場合、registrationインストール中ワーカーをnullに設定する。

    2. registration待機中ワーカーがnullでなければ、並行して

      1. アクティベートregistrationで呼び出す。

サービスワーカー拡張イベント集合の更新

入力

workerサービスワーカー

eventイベント

出力

なし

  1. アサート: eventdispatchフラグは未設定である。

  2. worker拡張イベント集合の各itemについて:

    1. itemアクティブでなければ、拡張イベント集合からitemを削除する。

  3. eventアクティブであれば、拡張イベント集合eventを追加する。

登録解除

入力

jobジョブ

出力

なし

  1. jobオリジンjobスコープURLオリジンと一致しない場合:

    1. ジョブプロミス拒否jobと"SecurityError" DOMExceptionで呼び出す。

    2. ジョブ完了jobで呼び出し、これらの手順を中止する。

  2. 登録取得jobストレージキーjobスコープURLで実行した結果をregistrationとする。

  3. registrationがnullの場合:

    1. ジョブプロミス解決jobとfalseで呼び出す。

    2. ジョブ完了jobで呼び出し、これらの手順を中止する。

  4. 登録マップ[(registrationストレージキー, jobスコープURL)]を削除する。

  5. ジョブプロミス解決jobとtrueで呼び出す。

  6. 登録クリア試行registrationで呼び出す。

    注: 登録クリア試行がここで登録クリアを発火しない場合、登録クリアは、最後のクライアントが登録利用している状態でアンロードされた時や、その登録のサービスワーカーのライフタイム延長プロミスが解決された際に再度試行される。

  7. ジョブ完了jobで呼び出す。

登録設定

入力

storage keyストレージキー

scopeURL

updateViaCacheキャッシュ経由更新モード

出力

registrationサービスワーカー登録

  1. 以下の手順をアトミックに実施する。

  2. scopeStringscopeフラグメント除外フラグ付きで直列化したものとする。

  3. registrationを新規サービスワーカー登録として、ストレージキーstorage keyに、スコープURLscopeに、キャッシュ経由更新モードupdateViaCacheに設定する。

  4. 登録マップ[(storage key, scopeString)]にregistrationを設定する。

  5. registrationを返す。

登録クリア

入力

registrationサービスワーカー登録

出力

なし

  1. 以下の手順をアトミックに実施する。

  2. registrationインストール中ワーカーがnullでなければ:

    1. 終了registrationインストール中ワーカーに対して呼び出す。

    2. ワーカー状態更新アルゴリズムをregistrationインストール中ワーカーと"redundant"で実行する。

    3. 登録状態更新アルゴリズムをregistration、"installing"、nullで実行する。

  3. registration待機中ワーカーがnullでなければ:

    1. 終了registration待機中ワーカーに対して呼び出す。

    2. ワーカー状態更新アルゴリズムをregistration待機中ワーカーと"redundant"で実行する。

    3. 登録状態更新アルゴリズムをregistration、"waiting"、nullで実行する。

  4. registrationアクティブワーカーがnullでなければ:

    1. 終了registrationアクティブワーカーに対して呼び出す。

    2. ワーカー状態更新アルゴリズムをregistrationアクティブワーカーと"redundant"で実行する。

    3. 登録状態更新アルゴリズムをregistration、"active"、nullで実行する。

登録クリア試行

入力

registrationサービスワーカー登録

出力

なし

  1. 次のすべてが満たされ、かつどのサービスワーカークライアントregistration利用していない場合、登録クリアregistrationで呼び出す:

登録状態更新

入力

registrationサービスワーカー登録

target、文字列("installing"、"waiting"、"active"のいずれか)

sourceサービスワーカーまたはnull

出力

なし

  1. registrationObjectsregistrationに関連付けられているすべてのServiceWorkerRegistrationオブジェクトを含む配列とする。

  2. targetが"installing"の場合:

    1. registrationインストール中ワーカーsourceに設定する。

    2. registrationObjectsの各registrationObjectについて:

      1. タスクキューを使い、registrationObjectinstalling属性をregistrationインストール中ワーカーがnullならnull、そうでなければサービスワーカーオブジェクト取得アルゴリズムをregistrationインストール中ワーカーregistrationObject関連設定オブジェクトで実行した結果に設定する。

  3. それ以外でtargetが"waiting"の場合:

    1. registration待機中ワーカーsourceに設定する。

    2. registrationObjectsの各registrationObjectについて:

      1. タスクキューを使い、registrationObjectwaiting属性をregistration待機中ワーカーがnullならnull、そうでなければサービスワーカーオブジェクト取得アルゴリズムをregistration待機中ワーカーregistrationObject関連設定オブジェクトで実行した結果に設定する。

  4. それ以外でtargetが"active"の場合:

    1. registrationアクティブワーカーsourceに設定する。

    2. registrationObjectsの各registrationObjectについて:

      1. タスクキューを使い、registrationObjectactive属性をregistrationアクティブワーカーがnullならnull、そうでなければサービスワーカーオブジェクト取得アルゴリズムをregistrationアクティブワーカーregistrationObject関連設定オブジェクトで実行した結果に設定する。

    タスクregistrationObject関連設定オブジェクト責任イベントループDOM操作タスクソース必ず利用する。

ワーカー状態の更新

入力

workerサービスワーカー

stateサービスワーカー状態

出力

なし

  1. アサート: stateは"parsed"でない。

    注: "parsed"は初期状態であり、サービスワーカーはこの状態に更新されることはない。

  2. worker状態stateに設定する。

  3. settingsObjectsを、環境設定オブジェクトのうち、オリジンworkerスクリプトURLオリジンと一致するもの全てとする。

  4. settingsObjectsの各settingsObjectについて、タスクをキューし、settingsObject責任イベントループ上でDOM操作タスクソースを利用して、以下の手順を実行する:

    1. objectMapsettingsObjectサービスワーカーオブジェクトマップとする。

    2. objectMap[worker]が存在しない場合、これらの手順を中止する。

    3. workerObjobjectMap[worker]とする。

    4. workerObjstate 属性をstateに設定する。

    5. statechangeという名前のイベントをworkerObjに発火する。

コントローラー変更の通知

入力

clientサービスワーカークライアント

出力

なし

  1. アサート: clientはnullでない。

  2. client環境設定オブジェクトの場合、タスクキューを使い、controllerchangeという名前のイベントをclient関連付けられているServiceWorkerContainer オブジェクトに発火する。

タスクclient責任イベントループDOM操作タスクソース必ず利用する。

サービスワーカー登録のマッチング

入力

storage keyストレージキー

clientURLURL

出力

サービスワーカー登録

  1. 以下の手順をアトミックに実施する。

  2. clientURLString直列化したclientURLとする。

  3. matchingScopeStringを空文字列とする。

  4. scopeStringSetを空リストとする。

  5. (entry storage key, entry scope)を登録マップキーから取り出して:

    1. storage key等しい場合、entry scopescopeStringSetの末尾に追加する。

  6. clientURLStringで始まるscopeStringSet内の最長値があれば、それをmatchingScopeStringに設定する。

    注: このステップのURL文字列マッチングはパス構造ではなくプレフィックスに基づく。例えば、"https://example.com/prefix-of/resource.html"というクライアントURL文字列は、"https://example.com/prefix"というスコープの登録に一致する。URL文字列比較は同一オリジンのセキュリティ上安全で、HTTP(S) URLは常にオリジン部分の末尾にスラッシュ付きで直列化される。

  7. matchingScopeをnullとする。

  8. matchingScopeStringが空文字列でなければ:

    1. matchingScopeパースしたmatchingScopeStringの結果に設定する。

    2. アサート: matchingScopeオリジンclientURLオリジン同一オリジンである。

  9. storage keymatchingScopeを使い登録取得アルゴリズムを実行した結果を返す。

登録取得

入力

storage keyストレージキー

scopeURL

出力

サービスワーカー登録

  1. 以下の手順をアトミックに実施する。

  2. scopeStringを空文字列とする。

  3. scopeがnullでなければ、scopeStringフラグメント除外フラグ付き直列化したscopeに設定する。

  4. (entry storage key, entry scope)→registration登録マップから取り出して:

    1. storage key等しいかつscopeStringentry scopeに一致するなら、registrationを返す。

  5. nullを返す。

最新ワーカー取得

入力

registrationサービスワーカー登録

出力

newestWorkerサービスワーカー

  1. 以下の手順をアトミックに実施する。

  2. newestWorkerをnullとする。

  3. registrationインストール中ワーカーがnullでなければ、newestWorkerregistrationインストール中ワーカーに設定する。

  4. それ以外でregistration待機中ワーカーがnullでなければ、newestWorkerregistration待機中ワーカーに設定する。

  5. それ以外でregistrationアクティブワーカーがnullでなければ、newestWorkerregistrationアクティブワーカーに設定する。

  6. newestWorkerを返す。

サービスワーカーに保留イベントがないか

入力

workerサービスワーカー

出力

trueまたはfalse(真偽値)

  1. worker拡張イベント集合の各eventについて:

    1. eventアクティブなら、falseを返す。

  2. trueを返す。

クライアント作成

入力

clientサービスワーカークライアント

出力

clientObjectClient オブジェクト

  1. clientObjectを新規Clientオブジェクトとして作成する。

  2. clientObjectサービスワーカークライアントclientに設定する。

  3. clientObjectを返す。

ウィンドウクライアント作成

入力

clientサービスワーカークライアント

frameType、文字列

visibilityState、文字列

focusState、真偽値

ancestorOriginsList、リスト

出力

windowClientWindowClient オブジェクト

  1. windowClientを新規WindowClientオブジェクトとして作成する。

  2. windowClientサービスワーカークライアントclientに設定する。

  3. windowClientフレームタイプframeTypeに設定する。

  4. windowClient表示状態visibilityStateに設定する。

  5. windowClientフォーカス状態focusStateに設定する。

  6. windowClientancestor origins arrayを、ancestorOriginsListから作成したFrozen Arrayに設定する。

  7. windowClientを返す。

フレームタイプ取得

入力

navigableナビゲーブル

出力

frameType、文字列

  1. navigableがnullでなければ、"nested"を返す。

  2. navigableアクティブなブラウジングコンテキスト補助的ブラウジングコンテキストであれば、"auxiliary"を返す。

  3. "top-level"を返す。

Get Client Promise解決

入力

clientサービスワーカークライアント

promiseプロミス

出力

なし

  1. client環境設定オブジェクトの場合:

    1. clientセキュアコンテキストでなければ、タスクキューによりpromiseを"SecurityError" DOMExceptionで拒否する。この際、promise関連設定オブジェクト責任イベントループおよびDOM操作タスクソースを利用し、これらの手順を中止する。

  2. それ以外:

    1. client作成URL潜在的に信頼できるURLでなければ、タスクキューによりpromiseを"SecurityError" DOMExceptionで拒否する。この際、promise関連設定オブジェクト責任イベントループおよびDOM操作タスクソースを利用し、これらの手順を中止する。

  3. client環境設定オブジェクトであり、ウィンドウクライアントでなければ:

    1. clientObjectクライアント作成アルゴリズムでclientを引数に実行した結果とする。

    2. タスクキューによりpromiseclientObjectで解決する。この際、promise関連設定オブジェクト責任イベントループおよびDOM操作タスクソースを利用し、これらの手順を中止する。

  4. それ以外:

    1. browsingContextをnullとする。

    2. client環境設定オブジェクトであれば、browsingContextclientグローバルオブジェクトブラウジングコンテキストに設定する。

    3. それ以外の場合、browsingContextclientターゲットブラウジングコンテキストに設定する。

    4. navigablebrowsingContextナビゲーブルで、アクティブなブラウジングコンテキストbrowsingContextのものとする。

    5. タスクキューで以下の手順をbrowsingContextイベントループ上、ユーザー操作タスクソースを使って実行:

      1. frameTypeフレームタイプ取得アルゴリズムをnavigableで実行した結果とする。

      2. visibilityStatebrowsingContextアクティブドキュメントvisibilityState属性値とする。

      3. focusStateフォーカス取得手順browsingContextアクティブドキュメントを引数に実行した結果とする。

      4. ancestorOriginsListを空リストとする。

      5. clientウィンドウクライアントの場合、ancestorOriginsListbrowsingContextアクティブドキュメント関連グローバルオブジェクトLocationオブジェクトのancestor origins listの関連リストに設定する。

      6. タスクキューで以下の手順をpromise関連設定オブジェクト責任イベントループ上、DOM操作タスクソースで実行:

        1. client廃棄フラグが設定されていれば、promiseをundefinedで解決し、これらの手順を中止する。

        2. windowClientウィンドウクライアント作成アルゴリズムでclientframeTypevisibilityStatefocusStateancestorOriginsListを引数に実行した結果とする。

        3. promisewindowClientで解決する。

キャッシュクエリ

入力

requestQueryリクエスト

optionsCacheQueryOptionsオブジェクト(オプション)

targetStorageリクエストレスポンスリスト(オプション)

出力

resultListリクエストレスポンスリスト

  1. resultListを空のリストとする。

  2. storageをnullとする。

  3. オプション引数targetStorageが省略された場合、storage関連リクエストレスポンスリストに設定する。

  4. それ以外の場合、storagetargetStorageに設定する。

  5. requestResponsestorageから取り出して:

    1. cachedRequestrequestResponseのリクエストとする。

    2. cachedResponserequestResponseのレスポンスとする。

    3. リクエストキャッシュ一致アルゴリズムをrequestQuerycachedRequestcachedResponseoptionsで実行し、trueなら:

      1. requestCopycachedRequestのコピーとする。

      2. responseCopycachedResponseのコピーとする。

      3. requestCopy/responseCopyresultListに追加する。

  6. resultListを返す。

リクエストがキャッシュ項目に一致するか

入力

requestQueryリクエスト

requestリクエスト

responseレスポンスまたはnull(オプション、省略時はnull)

optionsCacheQueryOptions オブジェクト(オプション)

出力

真偽値

  1. options["ignoreMethod"] がfalseで、requestメソッドGETでなければ、falseを返す。

  2. queryURLrequestQueryurlとする。

  3. cachedURLrequesturlとする。

  4. options["ignoreSearch"] がtrueなら:

    1. cachedURLクエリを空文字列に設定する。

    2. queryURLクエリを空文字列に設定する。

  5. queryURLフラグメント除外フラグ付きcachedURL等しくない場合、falseを返す。

  6. responseがnull、options["ignoreVary"] がtrue、またはresponseヘッダーリストVary含まない場合、trueを返す。

  7. fieldValuesリストとして、field-valuesresponseVaryヘッダー値に対応する要素を格納する。

  8. fieldValuesの各fieldValueについて:

    1. fieldValueが"*"に一致、またはfieldValuerequestヘッダーリスト結合値が、fieldValuerequestQueryヘッダーリスト結合値と一致しなければ、falseを返す。

  9. trueを返す。

バッチキャッシュ操作

入力

operationsリストキャッシュバッチ操作オブジェクトのリスト)

出力

resultListリクエストレスポンスリスト

  1. cache関連リクエストレスポンスリストとする。

  2. backupCachecacheのコピーで新規リクエストレスポンスリストとする。

  3. addedItemsを空のリストとする。

  4. 以下のサブステップをアトミックに試行する:

    1. resultListを空のリストとする。

    2. operationoperationsから取り出して:

      1. operationtypeが"delete"または"put"以外なら、TypeErrorを投げる。

      2. operationtypeが"delete"で、operationresponseがnullでなければ、TypeErrorを投げる。

      3. キャッシュクエリoperationrequestoperationoptionsaddedItemsで実行した結果が空でなければ、InvalidStateError DOMExceptionを投げる。

      4. requestResponsesを空のリストとする。

      5. operationtypeが"delete"なら:

        1. requestResponsesキャッシュクエリoperationrequestoperationoptionsで実行した結果に設定する。

        2. requestResponserequestResponsesから取り出して:

          1. item値がrequestResponseに一致するものをcacheから削除する。

      6. それ以外でoperationtypeが"put"なら:

        1. operationresponseがnullなら、TypeErrorを投げる。

        2. roperationrequestの関連リクエストに設定する。

        3. rurlスキームが"http"または"https"でなければ、TypeErrorを投げる。

        4. rメソッドGETでなければ、TypeErrorを投げる。

        5. operationoptionsがnullでなければ、TypeErrorを投げる。

        6. requestResponsesキャッシュクエリoperationrequestで実行した結果に設定する。

        7. requestResponserequestResponsesから取り出して:

          1. item値がrequestResponseに一致するものをcacheから削除する。

        8. operationrequest/operationresponsecacheに追加する。

        9. 前2ステップでキャッシュ書き込みが割り当てクォータ上限超過で失敗した場合、QuotaExceededError DOMExceptionを投げる。

        10. operationrequest/operationresponseaddedItemsに追加する。

      7. operationrequest/operationresponseresultListに追加する。

    3. resultListを返す。

  5. そして、例外が投げられた場合:

    1. 関連リクエストレスポンスリストから全てのitemを削除する。

    2. requestResponsebackupCacheから取り出して:

      1. requestResponseを関連リクエストレスポンスリストに追加する。

    3. 例外を投げる。

    注: 例外が投げられた場合、実装はバッチ操作ジョブ中にキャッシュストレージに加えた変更を元に戻す(ロールバック)する。

非同期モジュールか判定

入力

recordModule Record

moduleMapモジュールマップ

baseURL

seen集合URLの集合)

出力

真偽値

  1. recordCyclic Module Recordでなければ:

    1. falseを返す。

  2. record.[[Async]]がtrueなら:

    1. trueを返す。

  3. 文字列requestedrecord.[[RequestedModules]]から取り出して:

    1. urlモジュール指定子の解決アルゴリズムをbaserequestedで実行した結果とする。

    2. アサート: urlは失敗にならない。なぜならモジュール指定子の解決は同じ引数で事前に必ず成功しているため。

    3. seenurl含まない場合:

      1. urlseenに追加する。

      2. moduleMap[url]にrecordがなければ:

        1. falseを返す。

      3. 非同期モジュールか判定アルゴリズムを moduleMap[url]のrecordmoduleMapbaseseenで実行してtrueなら:

        1. trueを返す。

  4. falseを返す。

Race Responseの検索

入力

requestリクエスト

出力

レスポンスまたはnull

  1. registrationをnullとする。

  2. request非サブリソースリクエストの場合:

    1. requestreserved clientがnullなら、nullを返す。

    2. storage keyストレージキー取得アルゴリズムをrequestreserved clientで実行した結果に設定する。

    3. registrationサービスワーカー登録のマッチングアルゴリズムをstorage keyrequesturlで実行した結果に設定する。

  3. それ以外でrequestサブリソースリクエストの場合:

    1. clientrequestclientとする。

    2. clientアクティブサービスワーカーがnullなら、nullを返す。

    3. registrationclientアクティブサービスワーカー関連サービスワーカー登録に設定する。

  4. それ以外の場合、nullを返す。

  5. activeWorkerregistrationアクティブワーカーに設定する。

  6. mapactiveWorkerグローバルオブジェクトrace response mapに設定する。

  7. map[request]が存在する場合:

    1. entrymap[request]に設定する。

    2. mapからmap[request]を削除する。

    3. entryvalueが"pending"でなくなるまで待つ。

    4. entryvalueレスポンスであれば、entryvalueを返す。

  8. nullを返す。

付録B: 拡張HTTPヘッダー

サービスワーカーのスクリプトリクエスト

fetchによるサービスワーカースクリプトリソースのHTTPリクエストには、次のヘッダーが含まれる:

`Service-Worker`

このリクエストがサービスワーカースクリプトリソースリクエストであることを示す。

注: このヘッダーは管理者がリクエスト記録や脅威検知を行う際に役立つ。

サービスワーカーのスクリプトレスポンス

サービスワーカースクリプトリソースリクエストへのHTTPレスポンスには、次のヘッダーを含めることができる:

`Service-Worker-Allowed`

ユーザーエージェントがパス制限(スクリプトが制御できる最大のスコープURLを制限)の上限を、指定された値に上書きすることを示す。

注: 値はURLである。相対URLが指定された場合は、スクリプトのURLを基準にパースされる。

デフォルトのスコープ:
// 許容される最大スコープのデフォルトはスクリプトのパス(この例では "/js/")
// "/js/" の場合
navigator.serviceWorker.register("/js/sw.js").then(() => {
  console.log("デフォルトスコープ'/js/'でインストールに成功しました。");
});
Service-Worker-Allowedヘッダーなしで上位パス指定:
// スクリプトより上位パスへスコープを指定
// レスポンスにService-Worker-Allowedヘッダーなし
navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).catch(() => {
  console.error("パス制限違反でインストールに失敗しました。");
});
Service-Worker-Allowedヘッダー付きで上位パス指定:
// スクリプトより上位パスへスコープを指定
// レスポンスに "Service-Worker-Allowed : /" を含む
navigator.serviceWorker.register("/js/sw.js", { scope: "/" }).then(() => {
  console.log("最大許容スコープが'/'に上書きされ、インストールに成功しました。");
});
Service-Worker-Allowedヘッダーがあってもパス制限違反:
// スクリプトより上位パスへスコープを指定
// レスポンスに "Service-Worker-Allowed : /foo" を含む
navigator.serviceWorker.register("/foo/bar/sw.js", { scope: "/" }).catch(() => {
  console.error("スコープが上書き最大許容範囲外のため、インストールに失敗しました。");
});

構文

ABNFによる、サービスワーカースクリプトリソースリクエストとレスポンスで使われるヘッダー値の構文定義:

Service-Worker = %x73.63.72.69.70.74 ; "script", case-sensitive

注: Service-Worker-Allowedヘッダー値の検証はABNFではなくURLパースアルゴリズム(Updateアルゴリズム)で行われる。

8. 謝辞

Andrew Betts氏には、Jake Archibald氏、Jackson Gabbard氏、Tobie Langel氏、Robin Berjon氏、Patrick Lauke氏、Christian Heilmann氏など志を同じくする方々を集めて小さなワークショップを主催してくれたことに深く感謝します。その日の議論の明快さと、そこで示されたユースケースから多くの可能性が生まれました。さらに、オフライン問題への意識向上にも感謝します。彼のEdgeConfの運営と、オフラインを継続的なテーマにしたことで、この作業が前進する多くの機会とつながりが生まれました。

Anne van Kesteren氏には、Webプラットフォームの専門知識と標準化経験を惜しみなく提供いただき、サービスワーカーの開発を通じて助けていただきました。彼のURL、HTTP Fetch、Promises、DOMの実際の挙動についての先行研究がなければ、この仕様は不完全だったでしょう。同様に、Ian Hickson氏のWeb Worker仕様の厳密さにも多大な感謝を捧げます。

順不同ですが、設計指針や議論に深く感謝する方々:Jungkee Song氏、Alec Flett氏、David Barrett-Kahn氏、Aaron Boodman氏、Michael Nordman氏、Tom Ashworth氏、Kinuko Yasuda氏、Darin Fisher氏、Jonas Sicking氏、Jesús Leganés Combarro氏、Mark Christian氏、Dave Hermann氏、Yehuda Katz氏、François Remy氏、Ilya Grigorik氏、Will Chan氏、Domenic Denicola氏、Nikhil Marathe氏、Yves Lafon氏、Adam Barth氏、Greg Simon氏、Devdatta Akhawe氏、Dominic Cooney氏、Jeffrey Yasskin氏、Joshua Bell氏、Boris Zbarsky氏、Matt Falkenhagen氏、Tobie Langel氏、Gavin Peters氏、Ben Kelly氏、Hiroki Nakagawa氏、Jake Archibald氏、Josh Soref氏、Jinho Bang氏、Yutaka Hirano氏、Michael(tm) Smith氏、isonmad氏、Ali Alabbas氏、Philip Jägenstedt氏、Mike Pennisi氏、Eric Willigers氏。

Jason Weber氏、Chris Wilson氏、Paul Kinlan氏、Ehsan Akhgari氏、Daniel Austin氏にも、要件や標準化プロセスに関して貴重かつ的確なフィードバックをいただきました。

著者らは、Dimitri Glazkov氏にも感謝します。彼のスクリプトやフォーマットツールは、この仕様書の作成に不可欠でした。また、彼の多大なガイダンスにも感謝します。

Vivian Cromwell氏、Greg Simon氏、Alex Komoroske氏、Wonsuk Lee氏、Seojin Kim氏にも、その専門的な支援に感謝します。

適合性

文書の規約

適合性要件は、記述的なアサーションとRFC 2119の用語を組み合わせて表現されています。 現行標準の定義部分では、「MUST」「MUST NOT」「REQUIRED」「SHALL」「SHALL NOT」「SHOULD」「SHOULD NOT」「RECOMMENDED」「MAY」「OPTIONAL」といったキーワードは、RFC 2119で定義されている通りに解釈されます。 ただし、可読性のため、本仕様書ではこれらの単語は全て大文字では記載されていません。

本仕様書のすべての本文は現行標準ですが、明示的に非現行標準と示された節、例、および注記は除きます。[RFC2119]

本仕様書における例は、「例えば」で始まるか、class="example"で現行標準の本文から区別されています。例えば:

これは情報提供的な例です。

情報提供的な注記は「注」と始まり、class="note"で現行標準の本文から区別されています。例えば:

注:これは情報提供的な注記です。

適合性のあるアルゴリズム

アルゴリズムの一部として命令形で記述された要件(「先頭の空白文字を削除する」や「falseを返し、これらの手順を中止する」など)は、アルゴリズムの導入部で用いられているキーワード("must"、"should"、"may"など)の意味で解釈されます。

アルゴリズムや具体的な手順として記述された適合性要件は、最終的な結果が同等である限り、どのような方法で実装しても構いません。 とりわけ、本仕様書で定義されるアルゴリズムは理解しやすいことを目的としており、性能のためのものではありません。 実装者は最適化することが推奨されます。

索引

この仕様で定義される用語

参照によって定義される用語

参考文献

現行標準の参考文献

[CSP-NEXT]
Scripting Policy. 編集者草案. URL: https://wicg.github.io/csp-next/scripting-policy.html
[CSP3]
Mike West; Antonio Sartori. Content Security Policy Level 3. 2025年2月6日. 作業草案. URL: https://www.w3.org/TR/CSP3/
[DOM]
Anne van Kesteren. DOM Standard. 現行標準. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch Standard. 現行標準. URL: https://fetch.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink. File API. 2024年12月4日. 作業草案. URL: https://www.w3.org/TR/FileAPI/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. 2024年11月7日. 作業草案. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML Standard. 現行標準. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. 現行標準. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME Sniffing Standard. 現行標準. URL: https://mimesniff.spec.whatwg.org/
[NAVIGATION-TIMING-2]
Yoav Weiss; Noam Rosenthal. Navigation Timing Level 2. 2025年2月13日. 作業草案. URL: https://www.w3.org/TR/navigation-timing-2/
[PAGE-LIFECYCLE]
Page Lifecycle. コミュニティグループ草案. URL: https://wicg.github.io/page-lifecycle/
[PAGE-VISIBILITY]
Jatinder Mann; Arvind Jain. Page Visibility (第二版). 2013年10月29日. 勧告. URL: https://www.w3.org/TR/page-visibility/
[RFC2119]
S. Bradner. Key words for use in RFCs to Indicate Requirement Levels. 1997年3月. Best Current Practice. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC5234]
D. Crocker, Ed.; P. Overell. Augmented BNF for Syntax Specifications: ABNF. 2008年1月. インターネット標準. URL: https://www.rfc-editor.org/rfc/rfc5234
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Message Syntax and Routing. 2014年6月. 提案標準. URL: https://httpwg.org/specs/rfc7230.html
[RFC7231]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): Semantics and Content. 2014年6月. 提案標準. URL: https://httpwg.org/specs/rfc7231.html
[SCREEN-CAPTURE]
Jan-Ivar Bruaroey; Elad Alon. Screen Capture. 2025年2月13日. 作業草案. URL: https://www.w3.org/TR/screen-capture/
[SECURE-CONTEXTS]
Mike West. Secure Contexts. 2023年11月10日. 候補勧告草案. URL: https://www.w3.org/TR/secure-contexts/
[STORAGE]
Anne van Kesteren. Storage Standard. 現行標準. URL: https://storage.spec.whatwg.org/
[STREAMS]
Adam Rice; et al. Streams Standard. 現行標準. URL: https://streams.spec.whatwg.org/
[TRUSTED-TYPES]
Krzysztof Kotowicz. Trusted Types. 2025年1月10日. 作業草案. URL: https://www.w3.org/TR/trusted-types/
[URL]
Anne van Kesteren. URL Standard. 現行標準. URL: https://url.spec.whatwg.org/
[URLPATTERN]
Ben Kelly; Jeremy Roman; 宍戸俊哉 (Shunya Shishido). URL Pattern Standard. 現行標準. URL: https://urlpattern.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. 現行標準. URL: https://webidl.spec.whatwg.org/

参考情報

[UNSANCTIONED-TRACKING]
Unsanctioned Web Tracking. 2015年7月17日. W3C TAGのファインディング. URL: https://www.w3.org/2001/tag/doc/unsanctioned-tracking/

IDL索引

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorker : EventTarget {
  readonly attribute USVString scriptURL;
  readonly attribute ServiceWorkerState state;
  undefined postMessage(any message, sequence<object> transfer);
  undefined postMessage(any message, optional StructuredSerializeOptions options = {});

  // event
  attribute EventHandler onstatechange;
};
ServiceWorker includes AbstractWorker;

enum ServiceWorkerState {
  "parsed",
  "installing",
  "installed",
  "activating",
  "activated",
  "redundant"
};

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerRegistration : EventTarget {
  readonly attribute ServiceWorker? installing;
  readonly attribute ServiceWorker? waiting;
  readonly attribute ServiceWorker? active;
  [SameObject] readonly attribute NavigationPreloadManager navigationPreload;

  readonly attribute USVString scope;
  readonly attribute ServiceWorkerUpdateViaCache updateViaCache;

  [NewObject] Promise<undefined> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

enum ServiceWorkerUpdateViaCache {
  "imports",
  "all",
  "none"
};

partial interface Navigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

partial interface WorkerNavigator {
  [SecureContext, SameObject] readonly attribute ServiceWorkerContainer serviceWorker;
};

[SecureContext, Exposed=(Window,Worker)]
interface ServiceWorkerContainer : EventTarget {
  readonly attribute ServiceWorker? controller;
  readonly attribute Promise<ServiceWorkerRegistration> ready;

  [NewObject] Promise<ServiceWorkerRegistration> register((TrustedScriptURL or USVString) scriptURL, optional RegistrationOptions options = {});

  [NewObject] Promise<(ServiceWorkerRegistration or undefined)> getRegistration(optional USVString clientURL = "");
  [NewObject] Promise<FrozenArray<ServiceWorkerRegistration>> getRegistrations();

  undefined startMessages();


  // events
  attribute EventHandler oncontrollerchange;
  attribute EventHandler onmessage; // event.source of message events is ServiceWorker object
  attribute EventHandler onmessageerror;
};

dictionary RegistrationOptions {
  USVString scope;
  WorkerType type = "classic";
  ServiceWorkerUpdateViaCache updateViaCache = "imports";
};

[SecureContext, Exposed=(Window,Worker)]
interface NavigationPreloadManager {
  Promise<undefined> enable();
  Promise<undefined> disable();
  Promise<undefined> setHeaderValue(ByteString value);
  Promise<NavigationPreloadState> getState();
};

dictionary NavigationPreloadState {
  boolean enabled = false;
  ByteString headerValue;
};

[Global=(Worker,ServiceWorker), Exposed=ServiceWorker, SecureContext]
interface ServiceWorkerGlobalScope : WorkerGlobalScope {
  [SameObject] readonly attribute Clients clients;
  [SameObject] readonly attribute ServiceWorkerRegistration registration;
  [SameObject] readonly attribute ServiceWorker serviceWorker;

  [NewObject] Promise<undefined> skipWaiting();

  attribute EventHandler oninstall;
  attribute EventHandler onactivate;
  attribute EventHandler onfetch;

  attribute EventHandler onmessage;
  attribute EventHandler onmessageerror;
};

[Exposed=ServiceWorker]
interface Client {
  readonly attribute USVString url;
  readonly attribute FrameType frameType;
  readonly attribute DOMString id;
  readonly attribute ClientType type;
  undefined postMessage(any message, sequence<object> transfer);
  undefined postMessage(any message, optional StructuredSerializeOptions options = {});
};

[Exposed=ServiceWorker]
interface WindowClient : Client {
  readonly attribute VisibilityState visibilityState;
  readonly attribute boolean focused;
  [SameObject] readonly attribute FrozenArray<USVString> ancestorOrigins;
  [NewObject] Promise<WindowClient> focus();
  [NewObject] Promise<WindowClient?> navigate(USVString url);
};

enum FrameType {
  "auxiliary",
  "top-level",
  "nested",
  "none"
};

[Exposed=ServiceWorker]
interface Clients {
  // The objects returned will be new instances every time
  [NewObject] Promise<(Client or undefined)> get(DOMString id);
  [NewObject] Promise<FrozenArray<Client>> matchAll(optional ClientQueryOptions options = {});
  [NewObject] Promise<WindowClient?> openWindow(USVString url);
  [NewObject] Promise<undefined> claim();
};

dictionary ClientQueryOptions {
  boolean includeUncontrolled = false;
  ClientType type = "window";
};

enum ClientType {
  "window",
  "worker",
  "sharedworker",
  "all"
};

[Exposed=ServiceWorker]
interface ExtendableEvent : Event {
  constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
  undefined waitUntil(Promise<any> f);
};

dictionary ExtendableEventInit : EventInit {
  // Defined for the forward compatibility across the derived events
};

[Exposed=ServiceWorker]
interface InstallEvent : ExtendableEvent {
  constructor(DOMString type, optional ExtendableEventInit eventInitDict = {});
  Promise<undefined> addRoutes((RouterRule or sequence<RouterRule>) rules);
};

dictionary RouterRule {
  required RouterCondition condition;
  required RouterSource source;
};

dictionary RouterCondition {
  URLPatternCompatible urlPattern;
  ByteString requestMethod;
  RequestMode requestMode;
  RequestDestination requestDestination;
  RunningStatus runningStatus;

  sequence<RouterCondition> _or;
  RouterCondition not;
};

typedef (RouterSourceDict or RouterSourceEnum) RouterSource;

dictionary RouterSourceDict {
  DOMString cacheName;
};

enum RunningStatus { "running", "not-running" };
enum RouterSourceEnum {
  "cache",
  "fetch-event",
  "network",
  "race-network-and-fetch-handler"
};

[Exposed=ServiceWorker]
interface FetchEvent : ExtendableEvent {
  constructor(DOMString type, FetchEventInit eventInitDict);
  [SameObject] readonly attribute Request request;
  readonly attribute Promise<any> preloadResponse;
  readonly attribute DOMString clientId;
  readonly attribute DOMString resultingClientId;
  readonly attribute DOMString replacesClientId;
  readonly attribute Promise<undefined> handled;

  undefined respondWith(Promise<Response> r);
};

dictionary FetchEventInit : ExtendableEventInit {
  required Request request;
  Promise<any> preloadResponse;
  DOMString clientId = "";
  DOMString resultingClientId = "";
  DOMString replacesClientId = "";
  Promise<undefined> handled;
};

[Exposed=ServiceWorker]
interface ExtendableMessageEvent : ExtendableEvent {
  constructor(DOMString type, optional ExtendableMessageEventInit eventInitDict = {});
  readonly attribute any data;
  readonly attribute USVString origin;
  readonly attribute DOMString lastEventId;
  [SameObject] readonly attribute (Client or ServiceWorker or MessagePort)? source;
  readonly attribute FrozenArray<MessagePort> ports;
};

dictionary ExtendableMessageEventInit : ExtendableEventInit {
  any data = null;
  USVString origin = "";
  DOMString lastEventId = "";
  (Client or ServiceWorker or MessagePort)? source = null;
  sequence<MessagePort> ports = [];
};

partial interface mixin WindowOrWorkerGlobalScope {
  [SecureContext, SameObject] readonly attribute CacheStorage caches;
};

[SecureContext, Exposed=(Window,Worker)]
interface Cache {
  [NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Response>> matchAll(optional RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<undefined> add(RequestInfo request);
  [NewObject] Promise<undefined> addAll(sequence<RequestInfo> requests);
  [NewObject] Promise<undefined> put(RequestInfo request, Response response);
  [NewObject] Promise<boolean> delete(RequestInfo request, optional CacheQueryOptions options = {});
  [NewObject] Promise<FrozenArray<Request>> keys(optional RequestInfo request, optional CacheQueryOptions options = {});
};

dictionary CacheQueryOptions {
  boolean ignoreSearch = false;
  boolean ignoreMethod = false;
  boolean ignoreVary = false;
};

[SecureContext, Exposed=(Window,Worker)]
interface CacheStorage {
  [NewObject] Promise<(Response or undefined)> match(RequestInfo request, optional MultiCacheQueryOptions options = {});
  [NewObject] Promise<boolean> has(DOMString cacheName);
  [NewObject] Promise<Cache> open(DOMString cacheName);
  [NewObject] Promise<boolean> delete(DOMString cacheName);
  [NewObject] Promise<sequence<DOMString>> keys();
};

dictionary MultiCacheQueryOptions : CacheQueryOptions {
  DOMString cacheName;
};

課題索引

このセクションの挙動はまだ完全に仕様化されておらず、HTML標準で仕様化される予定です。作業はissueおよびpull requestで追跡されています。
作成される予定の環境設定オブジェクトを使用し、具体的な環境設定オブジェクトは使用しません。これはサービスワーカーの独自の処理モデルによるもので、他のWebワーカーの処理モデルとは異なります。HTML標準のスクリプト取得アルゴリズムは本来他のWebワーカー向けに設計されており、実行環境の環境設定オブジェクトを必要としますが、サービスワーカーはスクリプトを更新アルゴリズムで個別に取得し、その後サービスワーカー実行アルゴリズムを通して複数回スクリプトが実行されます。
HTMLのクラシックワーカースクリプト取得アルゴリズム及びモジュールワーカースクリプトグラフ取得アルゴリズムはjobclientを引数に取ります。jobclientソフト更新アルゴリズムから渡される際にnullとなっています。
MDN

Cache/add

In all current engines.

Firefox41+Safari11.1+Chrome44+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet4.0+Opera Mobile?
MDN

Cache/addAll

In all current engines.

Firefox41+Safari11.1+Chrome46+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Cache/delete

In all current engines.

Firefox41+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Cache/keys

In all current engines.

Firefox41+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Cache/match

In all current engines.

Firefox41+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Cache/matchAll

In all current engines.

Firefox41+Safari11.1+Chrome47+
Opera34+Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Cache/put

In all current engines.

Firefox41+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet4.0+Opera Mobile?
MDN

Cache

In all current engines.

Firefox41+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet4.0+Opera Mobile?
MDN

CacheStorage/delete

In all current engines.

Firefox41+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CacheStorage/has

In all current engines.

Firefox41+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CacheStorage/keys

In all current engines.

Firefox41+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CacheStorage/match

In all current engines.

Firefox41+Safari11.1+Chrome54+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CacheStorage/open

In all current engines.

Firefox41+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

CacheStorage

In all current engines.

Firefox41+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Client/frameType

In all current engines.

Firefox44+Safari11.1+Chrome43+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Client/id

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Client/postMessage

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Client/type

In all current engines.

Firefox54+Safari11.1+Chrome60+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Client/url

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Client

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Clients/claim

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Clients/get

In all current engines.

Firefox45+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Clients/matchAll

In all current engines.

Firefox54+Safari11.1+Chrome42+
Opera29+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile29+
MDN

Clients/openWindow

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera38+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile41+
MDN

Clients

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableEvent/ExtendableEvent

In all current engines.

Firefox44+Safari11.1+Chrome41+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ExtendableEvent/waitUntil

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ExtendableEvent

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ExtendableMessageEvent/ExtendableMessageEvent

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableMessageEvent/data

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableMessageEvent/lastEventId

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableMessageEvent/origin

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableMessageEvent/ports

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableMessageEvent/source

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ExtendableMessageEvent

In all current engines.

Firefox44+Safari11.1+Chrome51+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/FetchEvent

In all current engines.

Firefox44+Safari11.1+Chrome44+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/clientId

In all current engines.

Firefox45+Safari11.1+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/handled

In all current engines.

Firefox84+Safari16+Chrome86+
Opera?Edge86+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/preloadResponse

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/replacesClientId

In no current engines.

FirefoxNoneSafariNoneChromeNone
Opera?EdgeNone
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/request

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/respondWith

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

FetchEvent/resultingClientId

In all current engines.

Firefox65+Safari16+Chrome72+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile50+
MDN

FetchEvent

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

NavigationPreloadManager/disable

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

NavigationPreloadManager/enable

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

NavigationPreloadManager/getState

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

NavigationPreloadManager/setHeaderValue

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

NavigationPreloadManager

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Navigator/serviceWorker

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorker/postMessage

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorker/postMessage

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorker/scriptURL

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorker/state

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorker/statechange_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorker

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/controller

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/controllerchange_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/getRegistration

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/getRegistrations

In all current engines.

Firefox44+Safari11.1+Chrome45+
Opera27+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView40+Samsung Internet4.0+Opera Mobile27+
MDN

ServiceWorkerContainer/message_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/ready

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/register

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerContainer/startMessages

In all current engines.

Firefox64+Safari11.1+Chrome74+
Opera?Edge79+
Edge (Legacy)?IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile50+
MDN

ServiceWorkerContainer

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerGlobalScope/activate_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/activate_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/clients

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/fetch_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/install_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/message_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/message_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerGlobalScope/registration

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera26+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile26+
MDN

ServiceWorkerGlobalScope/skipWaiting

In all current engines.

Firefox44+Safari11.1+Chrome41+
Opera25+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile25+
MDN

ServiceWorkerGlobalScope

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera24+Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile24+
MDN

ServiceWorkerRegistration/active

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration/installing

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration/navigationPreload

In all current engines.

Firefox99+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet4.0+Opera Mobile?
MDN

ServiceWorkerRegistration/scope

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration/unregister

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration/update

In all current engines.

Firefox44+Safari11.1+Chrome45+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet4.0+Opera Mobile?
MDN

ServiceWorkerRegistration/updatefound_event

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration/updateViaCache

In all current engines.

Firefox57+Safari11.1+Chrome68+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration/waiting

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

ServiceWorkerRegistration

In all current engines.

Firefox44+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WindowClient/focus

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WindowClient/focused

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WindowClient/navigate

In all current engines.

Firefox50+Safari16+Chrome49+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView42+Samsung Internet4.0+Opera Mobile?
MDN

WindowClient/visibilityState

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

WindowClient

In all current engines.

Firefox44+Safari11.1+Chrome42+
Opera?Edge79+
Edge (Legacy)17+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

caches

In all current engines.

Firefox41+Safari11.1+Chrome40+
Opera?Edge79+
Edge (Legacy)16+IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?
MDN

Headers/Service-Worker-Navigation-Preload

In all current engines.

Firefoxpreview+Safari15.4+Chrome59+
Opera?Edge79+
Edge (Legacy)18IENone
Firefox for Android?iOS Safari?Chrome for Android?Android WebView?Samsung Internet?Opera Mobile?