サービスワーカー ナイトリー

W3C 候補勧告草案,

この文書の詳細
このバージョン:
https://www.w3.org/TR/2026/CRD-service-workers-20260917/
最新版公開バージョン:
https://www.w3.org/TR/service-workers/
編集者ドラフト:
https://w3c.github.io/ServiceWorker/
以前のバージョン:
履歴:
https://www.w3.org/standards/history/service-workers/
実装レポート:
https://wpt.fyi/results/service-workers
テストスイート:
https://github.com/web-platform-tests/wpt/tree/master/service-workers
フィードバック:
GitHub
仕様内インライン
編集者:
(Microsoft)
(Google)
前任編集者:
(Google)
(Google)
(Microsoft、2018年4月までSamsungを代表)
(Google)

概要

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

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

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

この文書のステータス

このセクションは、本書が公開された時点でのステータスについて説明しています。現在のW3Cの公開文書一覧とこの技術報告書の最新版は、W3C標準およびドラフト一覧で確認できます。

この文書はWebアプリケーション作業グループによって 勧告候補ドラフトとして勧告プロセスに従い公開されました。 勧告候補として公開されたことは、W3Cおよびその会員による支持を意味するものではありません。 勧告候補ドラフトは、ワーキンググループが後続の勧告候補スナップショットに含める意図がある、以前の勧告候補からの変更を統合しています。

これはドラフト文書であり、今後いつでも更新、差替え、または他の文書によって廃止される可能性があります。 本文書を進行中の作業以外のものとして引用することは不適切です。

これはリビングドキュメントです。読者は、本仕様に未実装の機能や今後細部が変更される可能性があることに注意してください。Service Workers 1は、W3C勧告に向けて進んでいるバージョンです。

この文書は、W3C特許ポリシーの下で運営されるグループによって作成されました。W3Cは、グループの成果物に関連してなされた公開特許開示リストを管理しています。そのページには特許開示の手続きも記載されています。個人が「本質的クレーム」を含む特許を実際に知っている場合には、W3C特許ポリシーのセクション6に従ってその情報を開示する必要があります。

この文書は 2025年8月18日 W3Cプロセス文書に準拠しています。

1. 動機

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

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

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

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

HTML5アプリケーションキャッシュを利用している開発者たちは、その設計のいくつかの属性が重大な問題を引き起こし、復旧不可能なエラーにつながると報告しています。Service Workerの主要な設計原則の一つは、エラーが常に回復可能であるべきだということです。Service Workerの更新処理の多くの詳細は、これらの問題を回避するために設計されています。

Service Workerはドキュメントではなくイベントとの関係によって起動および維持されます。この設計は、Shared WorkerやChrome Background Pagesに関する開発者やベンダーの経験を大いに参考にしています。これらのシステムから得られた重要な教訓は、リソースの節約およびバックグラウンドコンテキストの損失や再起動を開発者が意識できるようにするため、バックグラウンド処理コンテキストの実行時間を制限する必要があるということです。そのため、Service WorkerはChrome Event Pages(Background Pagesの後継)と非常によく似ています。Service Workerはドキュメントが結びついていなくてもユーザーエージェントによって起動されることがあり、ほぼいつでもユーザーエージェントによって終了される可能性があります。概念的には、Service Workerは、ドキュメントからのメッセージを一度も処理せずに開始・イベント処理・終了することができるShared Workerと捉えることができます。開発者は、Service Workerが1秒間に何度も起動や終了される可能性があることを忘れないよう注意してください。

Service Workerは、オリジンで実行される汎用的かつイベント駆動で時間制限のあるスクリプトコンテキストです。これらの特徴により、特定のドキュメントのコンテキストを超えて動作する実行時サービス(例:プッシュ通知の処理、バックグラウンドデータ同期、他オリジンからのリソース要求への応答、高コストなデータの一元的な更新受信(例:位置情報やジャイロスコープ)など)の受け口として自然に活用できます。

2. モデル

2.1. サービスワーカー

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

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

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

サービスワーカーは、"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. サービスワーカーのタイミング

サービスワーカーは、後に ナビゲーションタイミングAPIや リソースタイミングAPI によって公開される特定の時点を記録します。

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

開始時刻

DOMHighResTimeStamp、 初期値は0。

fetchイベント配送時刻

DOMHighResTimeStamp、 初期値は0。

ワーカーのルーター評価開始時刻

DOMHighResTimeStamp、 初期値は0。

ワーカーのキャッシュ検索開始時刻

DOMHighResTimeStamp、 初期値は0。

ワーカーの一致したルーターソース

DOMString、 初期値は空文字列。

ワーカーの最終ルーターソース

DOMString、 初期値は空文字列。

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

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

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

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

サービスワーカー登録には、関連付けられたインストール中ワーカー(サービスワーカーまたは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を返し、それ以外の場合はサービスワークラクライアントの作成URLのoriginを返します。

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

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

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

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

2.5. 制御と利用

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

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

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

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

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

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

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

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

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

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

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

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

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

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

fetchがHTTP fetchを経由する場合、ワークラクライアントのアクティブサービスワーカーはサービスワーカー登録一致の結果になります。 それ以外の場合、ワークラクライアントのoriginが不透明なoriginである場合や、リクエストのURLがblob 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. objectMap を environment の サービスワーカーオブジェクトマップとする。

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

    1. serviceWorkerObj を environment の Realm で新規作成した ServiceWorker とし、serviceWorker に関連付ける。

    2. serviceWorkerObj の state を serviceWorker の state に設定する。

    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. message と options を引数に postMessage(message, options) を呼び出す。

3.1.5. postMessage(message, options)

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

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

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

  3. incumbentGlobal を incumbentSettings の グローバルオブジェクトとする。

  4. serializeWithTransferResult を StructuredSerializeWithTransfer(message, options["transfer"])の結果とする。 例外が発生した場合はそのまま投げる。

  5. Should Skip Eventアルゴリズムを"message"と serviceWorkerで実行し、その結果がtrueなら終了。

  6. 以下のサブステップを並列処理する:

    1. Run Service Workerアルゴリズムを serviceWorkerで実行し、結果がfailureなら終了。

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

      1. source を incumbentGlobal の型によって以下のように決定:

        ServiceWorkerGlobalScope
        incumbentGlobal の service worker(関連設定オブジェクトの serviceWorker の グローバルオブジェクトで表す)の サービスワーカーオブジェクト取得結果
        Window
        incumbentGlobal の 関連設定オブジェクト を表す新しい WindowClient オブジェクト
        その他
        incumbentGlobal の関連ワーカーを表す新しい Client オブジェクト
      2. origin を incumbentSettings の originとする。

      3. destination を serviceWorker に紐付いた ServiceWorkerGlobalScope オブジェクトとする。

      4. deserializeRecord を StructuredDeserializeWithTransfer(serializeWithTransferResult, destination の Realm) の結果とする。

        例外なら e を event作成(名前: messageerror、 ExtendableMessageEvent 使用)として origin を origin、 source 属性を source で初期化したものとする。

      5. Else:

        1. messageClone を deserializeRecord.[[Deserialized]]とする。

        2. newPorts を 新しい 凍結配列 とし、deserializeRecord.[[TransferredValues]]内の全ての MessagePort オブジェクト(順序維持)を格納する。

        3. e を event作成(名前: message、 ExtendableMessageEvent 使用) として、 origin を origin、 source 属性を source、 data 属性を messageClone、 ports 属性を newPorts で初期化したものとする。

      6. eをdestinationにディスパッチ する。

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

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<ServiceWorkerRegistration> update();
  [NewObject] Promise<boolean> unregister();

  // event
  attribute EventHandler onupdatefound;
};

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

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

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

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

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

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

    1. registrationObjectをenvironmentのRealmで新規作成したServiceWorkerRegistrationとする。

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

    3. registrationObjectのinstalling属性をnullに設定する。

    4. registrationObjectのwaiting属性をnullに設定する。

    5. registrationObjectのactive属性をnullに設定する。

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

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

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

    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の関連グローバルオブジェクトglobalObjectがServiceWorkerGlobalScopeオブジェクトであり、globalObjectの関連サービスワーカーのstateが"installing"の場合、失敗したpromise("InvalidStateError"DOMException)を返して中断。

  5. promiseをpromiseとする。

  6. jobをジョブ作成アルゴリズムで、update、registrationのstorage key、registrationのscope url、newestWorkerのscript url、promise、thisの関連設定オブジェクトを引数に実行した結果にする。

  7. jobのworker typeをnewestWorkerのtypeに設定する。

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

  9. promiseを返す。

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

unregister()メソッド手順:

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

  2. promiseを新規promiseとする。

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

  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 が取得される元)に関連付けられています。

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

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

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

  1. clientをthisのサービスワークラクライアントとする。

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

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

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

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

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

  2. readyPromiseをthisのready promiseとする。

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

    1. clientをthisの サービスワークラクライアントとする。

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

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

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

  4. readyPromiseを返す。

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

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

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

  1. pをプロミスとする。

  2. scriptURLに、TrustedScriptURL、 thisの関連グローバルオブジェクト、 scriptURL、"ServiceWorkerContainer register"、および"script"を引数に、Get Trusted Type compliant stringを呼び出した結果を設定する。

  3. clientに、thisのservice workerクライアントを設定する。

  4. scriptURLに、thisの関連設定オブジェクトのAPI基準URLでscriptURLを構文解析した結果を設定する。

  5. scopeURLをnullにする。

  6. もしoptions["scope"] が存在する場合、options["scope"] をthisの関連設定オブジェクトの API基準URLで構文解析した結果をscopeURLに設定する。

  7. Start Registerを、 scopeURL、scriptURL、p、client、 clientの作成URL、 options["type"], およびoptions["updateViaCache"] を引数として呼び出す。

  8. pを返す。

getRegistration(clientURL) メソッド手順:

  1. clientを、これのサービスワーカークライアントとする。

  2. storage keyを、clientを与えてストレージキーを取得するを実行した結果とする。

  3. clientURLを、これの関連設定オブジェクトのAPI基底URLを用いてclientURLを構文解析した結果とする。

  4. clientURLが失敗である場合、TypeErrorで拒否されたプロミスを返す。

  5. clientURLのフラグメントをnullに設定する。

  6. clientURLのオリジンが、 clientのオリジンでない場合、「SecurityError」 DOMExceptionで拒否されたpromiseを返す。

  7. promiseを新しいプロミスとする。

  8. 次の下位手順を並列に実行する:

    1. registrationを、storage keyおよびclientURLを与えてサービスワーカー登録を照合するを実行した結果とする。

    2. promiseの関連設定オブジェクトの担当イベントループ上で、DOM操作タスクソースを使用して、次の手順を実行するタスクをキューに入れる:

      1. registrationがnullである場合、promiseを undefinedで解決し、これらの手順を中止する。

      2. promiseを、promiseの関連設定オブジェクト内で registrationを表すサービスワーカー登録オブジェクトを取得する結果で解決する。

  9. promiseを返す。

getRegistrations() メソッド手順:

  1. clientを、これのサービスワーカー クライアントとする。

  2. client storage keyを、clientを与えてストレージキーを取得するを実行した結果とする。

  3. promiseを新しい プロミスとする。

  4. 次の手順を並列に実行する:

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

    2. 各登録マップの (storage key, scope) → registrationについて:

      1. storage keyがclient storage keyと等しい場合、 registrationをregistrationsに付加する。

    3. promiseの関連設定オブジェクトの担当イベントループ上で、DOM操作タスクソースを使用して、 次の手順を実行するタスクをキューに入れる:

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

      2. registrationsの各registrationについて反復する:

        1. registrationObjを、promiseの関連設定 オブジェクト内でregistrationを表すサービスワーカー登録オブジェクトを 取得する結果とする。

        2. registrationObjを registrationObjectsに付加する。

      3. promiseを、promiseの関連レルム内の registrationObjectsの新しい固定配列で解決する。

  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 MessageEvent サービスワークラクライアントがサービスワーカーからメッセージを受信したとき。postMessage(message, options)参照。
messageerror MessageEvent サービスワークラクライアントがサービスワーカーからデシリアライズできないメッセージを受信したとき。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 を新しい プロミスとする。

  2. 次の手順を並列に実行する:

    1. registration を this に 関連付けられたサービスワーカー登録とする。

    2. registration のアクティブワーカーが null の場合、promise のタスクをキューに入れる。これは promise の関連する設定オブジェクトの担当イベントループ上で、DOM 操作タスクソースを使用し、 promise を "InvalidStateError" DOMException で拒否するためのものであり、 これらの手順を中止する。

    3. registration のナビゲーション プリロード有効フラグを設定する。

    4. promise のタスクをキューに入れる。これは promise の関連する設定オブジェクトの担当イベントループ上で、DOM 操作タスクソースを使用し、 promise を undefined で解決するためのものである。

  3. promise を返す。

disable() メソッドの手順:

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

  2. 次の手順を 並列に 実行する:

    1. registration を this に関連付けられた service worker registration とする。

    2. registration の active worker が null なら、promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、reject するための task をキューに入れ、promise を "InvalidStateError" の DOMException で reject し、 これらの手順を中止する。

    3. registration の navigation preload enabled flag を解除する。

    4. promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、 promise を undefined で resolve するための task をキューに入れる。

  3. promise を返す。

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

  1. value を 正規化 した結果を value とする。

  2. value が header value でない場合、TypeError で reject された promise を返す。

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

  4. 次の手順を 並列に 実行する:

    1. registration を this に関連付けられた service worker registration とする。

    2. registration の active worker が null なら、promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、reject するための task をキューに入れ、promise を "InvalidStateError" の DOMException で reject し、 これらの手順を中止する。

    3. registration の navigation preload header value を value に設定する。

    4. promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、 promise を undefined で resolve するための task をキューに入れる。

  5. promise を返す。

getState() メソッドの手順:

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

  2. 次の手順を 並列に 実行する:

    1. registration を this に関連付けられた service worker registration とする。

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

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

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

    5. promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して promise を state で resolve するための task をキューに入れる。

  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 worker (Service Worker)を持ちます。

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

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

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

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

4.1.1. clients

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

4.1.2. registration

registration の getter 手順は、 this の サービスワーカーが 属するサービスワーカー登録を、 this の 関連する設定群オブジェクト内で表す サービスワーカー登録オブジェクトを取得した結果を返すことです。

4.1.3. serviceWorker

serviceWorker の getter 手順は、 this の サービスワーカーを、 this の 関連する設定群オブジェクト内で表す サービスワーカーオブジェクトを取得した結果を返すことです。

4.1.4. skipWaiting()

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

skipWaiting() メソッドの手順:

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

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

    1. service worker の skip waitingフラグ を設定する。

    2. Try Activate を service 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 client (service 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手順は、this の frame type を返します。

4.2.3. id

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

4.2.4. type

type のgetter手順:

  1. client を this の service worker client とする。

  2. client が environment settings object なら:

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

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

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

  3. それ以外の場合:

    1. "window" を返す。

4.2.5. postMessage(message, transfer)

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

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

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

4.2.6. postMessage(message, options)

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

  1. contextObject を this とする。

  2. sourceSettings を contextObject の relevant settings object とする。

  3. serializeWithTransferResult を StructuredSerializeWithTransfer(message, options["transfer"]) とする。 例外はあれば再スローする。

  4. 次の手順を 並列に 実行する:

    1. targetClient を null とする。

    2. 各 service worker client client について:

      1. client が contextObject の service worker client である場合、targetClient を client に設定し、 そして break する。

    3. targetClient が null の場合、return する。

    4. destination を、関連付けられた service worker client が targetClient である ServiceWorkerContainer オブジェクトとする。

    5. 次の手順を実行する task を、destination の client message queue に追加する:

      1. origin を sourceSettings の origin とする。

      2. source を、contextObject の relevant global object の service worker を targetClient 内で表す service worker object の取得 の結果とする。

      3. deserializeRecord を StructuredDeserializeWithTransfer(serializeWithTransferResult, destination の relevant Realm) とする。

        これが例外を投げた場合、それを捕捉し、destination で messageerror という名前の event を発火 する。MessageEvent を使用し、 その origin を origin で初期化し、source 属性を source で初期化し、その後これらの手順を中止する。

      4. messageClone を deserializeRecord.[[Deserialized]] とする。

      5. newPorts を、deserializeRecord.[[TransferredValues]] 内の すべての MessagePort オブジェクト(存在する場合)から成る新しい frozen array とする。

      6. destination で message という名前の event をディスパッチ する。MessageEvent を使用し、 その 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. この origin 内のいずれの Window も transient activation を持たない場合、"InvalidAccessError" の DOMException で reject された promise を返す。

  2. serviceWorkerEventLoop を、surrounding agent の event loop とする。

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

  4. task をキューに入れ、this に関連付けられた service worker client の responsible event loop 上で、user interaction task source を使用して次の手順を実行する:

    1. focusing steps を this の browsing context で実行する。

    2. frameType を、Get Frame Type を this の browsing context で実行した結果とする。

    3. visibilityState を this の browsing context の active document の visibilityState 属性値とする。

    4. focusState を、has focus steps を this の browsing context の active document で実行した結果とする。

    5. ancestorOriginsList を this の browsing context の active document の ancestor origins list の関連付けられたリストとする。

    6. task をキューに入れ、DOM manipulation task source を使用して serviceWorkerEventLoop 上で次の手順を実行する:

      1. windowClient を、Create Window Client を this に関連付けられた service worker client、frameType、visibilityState、 focusState、および ancestorOriginsList で実行した結果とする。

      2. windowClient の focus state が true の場合、promise を windowClient で resolve する。

      3. それ以外の場合、promise を TypeError で reject する。

  5. promise を返す。

4.2.11. navigate(url)

navigate(url) メソッド手順:

  1. url を、parsing を url と this の relevant settings object の API base URL で実行した結果とする。

  2. url が failure の場合、TypeError で reject された promise を返す。

  3. url が about:blank の場合、TypeError で reject された promise を返す。

  4. this に関連付けられた service worker client の active service worker が this の relevant global object の service worker でない場合、promise を TypeError で reject して返す。

  5. serviceWorkerEventLoop を、current global object の event loop とする。

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

  7. task をキューに入れ、this に関連付けられた service worker client の responsible event loop 上で、user interaction task source を使用して次の手順を実行する:

    1. browsingContext を this の browsing context とする。

    2. browsingContext の associated document が fully active でない場合、task をキューに入れて promise を TypeError で reject する。serviceWorkerEventLoop 上で DOM manipulation task source を使用し、これらの手順を中止する。

    3. HandleNavigate: Navigate を browsingContext から url へ、browsingContext の associated document を用いて、exceptionsEnabled を true として実行する。

    4. HandleNavigate とラベル付けされた手順で呼び出されたアルゴリズムの手順が throws した場合、task をキューに入れて promise を その例外で reject する。serviceWorkerEventLoop 上で DOM manipulation task source を使用し、これらの手順を中止する。

    5. frameType を、Get Frame Type を browsingContext で実行した結果とする。

    6. visibilityState を browsingContext の active document の visibilityState 属性値とする。

    7. focusState を、has focus steps を browsingContext の active document で実行した結果とする。

    8. ancestorOriginsList を browsingContext の active document の ancestor origins list の関連付けられたリストとする。

    9. task をキューに入れ、DOM manipulation task source を使用して serviceWorkerEventLoop 上で次の手順を実行する:

      1. browsingContext の Window オブジェクトの environment settings object の creation URL の origin が、same で service worker の origin と一致しない場合、 promise を null で resolve し、これらの手順を中止する。

      2. windowClient を、Create Window Client を this の service worker client、frameType、visibilityState、 focusState、および ancestorOriginsList で実行した結果とする。

      3. promise を windowClient で resolve する。

  8. promise を返す。

4.3. Clients

[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"
};

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

4.3.1. get(id)

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

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

  2. これらのサブステップを 並列に 実行する:

    1. 与えられた client に対して obtain a storage key を実行した結果が、関連付けられた service worker の containing service worker registration の storage key と equals である各 service worker client client について:

      1. client の id が id でない場合、continue する。

      2. client の execution ready flag が設定されるか、または client の discarded flag が設定されるまで待機する。

      3. client の execution ready flag が設定されている場合、promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、次の手順を実行するための task をキューに入れる:

        1. Resolve Get Client Promise を client と promise で呼び出す。

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

    2. promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して promise を undefined で resolve するための task をキューに入れる。

  3. promise を返す。

4.3.2. matchAll(options)

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

  1. promise を新しい プロミスとする。

  2. 次の手順を並列に実行する。

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

    2. client を与えてストレージキーを取得するを実行した結果が、 関連付けられたサービスワーカーの 包含サービス ワーカー登録のストレージキーと等しい、各サービスワーカークライアント client について、次を実行する。

      1. client の実行 準備完了フラグが設定されていないか、client の破棄済み フラグが設定されている場合、続行する。

      2. client がセキュアコンテキストでない場合、続行する。

      3. options["includeUncontrolled"] が false であり、かつ client のアクティブな サービスワーカーが、関連付けられたサービス ワーカーでない場合、続行する。

      4. client を targetClients に追加する。

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

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

    5. targetClients 内の各サービスワーカークライアント client について、次を実行する。

      1. options["type"] が "window" または "all" であり、かつ client が環境設定 オブジェクトでないか、またはウィンドウクライアントである場合、次を実行する。

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

        2. browsingContext を null とする。

        3. isClientEnumerable を true とする。

        4. client が環境 設定オブジェクトである場合、browsingContext を client のグローバル オブジェクトの閲覧コンテキストに設定する。

        5. そうでない場合、browsingContext を client の対象 閲覧コンテキストに設定する。

        6. タスクをキューに追加する。task が、ユーザーインタラクション タスクソースを使用して、browsingContext のイベントループ上で次の副手順を実行する。

          1. browsingContext が破棄されている場合、 isClientEnumerable を false に設定し、これらの 手順を中止する。

          2. client がウィンドウクライアントであり、 client の関連付けられた 文書が browsingContext のアクティブな文書でない場合、 isClientEnumerable を false に設定し、これらの 手順を中止する。

          3. windowData["frameType"] を、 browsingContext を用いてフレーム型を取得するを実行した 結果に設定する。

          4. windowData["visibilityState"] を、browsingContext のアクティブな文書の visibilityState 属性値に設定する。

          5. windowData["focusState"] を、 browsingContext のアクティブな文書を引数として、 フォーカスを持つかの手順 を実行した結果に設定する。

          6. client がウィンドウクライアント である場合、 windowData["ancestorOriginsList"] を browsingContext のアクティブな文書の祖先 オリジンリストに関連付けられたリストに設定する。

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

          注記: 待機は ブロッキング待機であるが、実装者は状態が壊れない限り、反復を並列に 実行してもよい。

        8. isClientEnumerable が true である場合、次を実行する。

          1. windowData を matchedWindowData に追加する。

      2. そうでなく、options["type"] が "worker" または "all" であり、かつ client が専用ワーカー クライアントであるか、または options["type"] が "sharedworker" または "all" であり、かつ client が共有ワーカークライアント である場合、次を実行する。

        1. client を matchedClients に追加する。

    6. task をキューに入れ、次の手順を promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して実行する:

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

      2. matchedWindowData 内の各 windowData について、次を実行する。

        1. windowClient を、 windowData["client"]、 windowData["frameType"]、 windowData["visibilityState"]、 windowData["focusState"]、および windowData["ancestorOriginsList"] を 引数としてウィンドウクライアントを作成する アルゴリズムを実行した結果とする。

        2. windowClient を clientObjects に付加する。

      3. matchedClients 内の各 client について、次を実行する。

        1. clientObject を、client を引数としてクライアントを作成するアルゴリズムを実行した 結果とする。

        2. clientObject を clientObjects に付加する。

      4. clientObjects を次のように並べ替える。

        注記: ウィンドウクライアントは常に ワーカークライアントより前に 配置される。

      5. promise の関連 Realmにおいて、 clientObjects の新しい固定配列で promise を解決する。

  3. promise を返す。

4.3.3. openWindow(url)

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

  1. url を、parsing を url と this の relevant settings object の API base URL で実行した結果とする。

  2. url が failure の場合、TypeError で reject された promise を返す。

  3. url が about:blank の場合、TypeError で reject された promise を返す。

  4. この origin 内のいずれの Window も transient activation を持たない場合、"InvalidAccessError" の DOMException で reject された promise を返す。

  5. serviceWorkerEventLoop を、current global object の event loop とする。

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

  7. これらのサブステップを 並列に 実行する:

    1. newContext を新しい top-level browsing context とする。

    2. task をキューに入れ、次の手順を newContext の Window オブジェクトの environment settings object の responsible event loop 上で、user interaction task source を使用して実行する:

      1. HandleNavigate: Navigate を newContext から url へ、exceptionsEnabled を true、 かつ historyHandling を "replace" として実行する。

      2. HandleNavigate とラベル付けされた手順で呼び出されたアルゴリズムの手順が throws した場合、task をキューに入れて promise をその例外で reject する。 serviceWorkerEventLoop 上で DOM manipulation task source を使用し、これらの手順を中止する。

      3. frameType を、Get Frame Type を newContext で実行した結果とする。

      4. visibilityState を newContext の active document の visibilityState 属性値とする。

      5. focusState を、has focus steps を newContext の active document を引数として実行した結果とする。

      6. ancestorOriginsList を newContext の active document の ancestor origins list の関連付けられたリストとする。

      7. task をキューに入れ、次の手順を serviceWorkerEventLoop 上で DOM manipulation task source を使用して実行する:

        1. obtain a storage key を newContext の Window オブジェクトの environment settings object で実行した結果が、equal で service worker の containing service worker registration の storage key と一致しない場合、promise を null で resolve し、 これらの手順を中止する。

        2. client を、Create Window Client を newContext の Window オブジェクトの environment settings object、frameType、 visibilityState、focusState、および ancestorOriginsList を引数として実行した結果とする。

        3. promise を client で resolve する。

  8. promise を返す。

4.3.4. claim()

claim() メソッドの手順:

  1. サービスワーカーがアクティブワーカーでない場合、"InvalidStateError" DOMException で却下されたプロミスを返す。

  2. promise を新しいプロミスとする。

  3. 次の副手順を並列に実行する。

    1. client を与えてストレージキーを取得するを実行した結果が、サービスワーカーの 包含サービス ワーカー登録のストレージキーと等しい、各サービスワーカークライアント client について、次を実行する。

      1. client の実行 準備完了フラグが設定されていないか、client の破棄済み フラグが設定されている場合、続行する。

      2. client がセキュアコンテキストでない場合、続行する。

      3. storage key を、client を与えてストレージキーを取得するを実行した結果とする。

      4. registration を、storage key および client の作成 URLを与えてサービスワーカー 登録を照合するを実行した結果とする。

      5. registration がサービス ワーカーの包含 サービスワーカー登録でない場合、続行する。

        注記: サービス ワーカーの包含 サービスワーカー登録が登録解除済み である場合、registration は null になる。

      6. client のアクティブな サービスワーカーがサービス ワーカーでない場合、次を実行する。

        1. client を引数としてサービス ワーカークライアントのアンロードを処理するを呼び出す。

        2. client のアクティブな サービスワーカーをサービス ワーカーに設定する。

        3. client を引数としてコントローラーの変更を 通知するアルゴリズムを呼び出す。

    2. task をキューに入れ、promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して promise を undefined で resolve する。

  4. promise を返す。

4.4. ExtendableEvent

[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
};

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つのライフサイクルイベント(install と activate)があります。 Service Worker は、ExtendableEvent インターフェースを install および activate イベントで利用します。

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

4.4.1. event.waitUntil(f)

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

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

lifetime promiseの追加 promise(promise)を event(ExtendableEvent)に対して行う手順:
  1. event の isTrusted 属性がfalseの場合、"InvalidStateError" DOMException をthrowする。

  2. event が active でない場合、"InvalidStateError" DOMException をthrowする。

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

  3. promise を event の extend lifetime promises に追加する。

  4. event の pending promises count を1増加させる。

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

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

    1. event の pending promises count を1減らす。

    2. event の pending promises count が0なら:

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

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

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

ユーザーエージェントは、Service Worker Has No Pending Events がその サービスワーカーに対して false を返す場合、 サービスワーカーを終了すべきではありません。

Service Workerや、拡張でイベントハンドラを定義するものは、独自の挙動を定義してもよいです。これにより、extend lifetime promisesによって処理時間を示唆したり、extend lifetime promises内のいずれかのPromiseがrejected状態であれば処理失敗を示唆できます。

注: Service Workerは、installing workerを「installed」として扱うのを、installイベントのextend lifetime promises内のすべてのPromiseが正常に解決されるまで遅延します。(該当のInstallアルゴリズム手順を参照。)Promiseのいずれかがrejectされた場合、インストールは失敗します。これは主に、Service Workerが依存するコアキャッシュがすべて準備されるまで「installed」と見なされないようにするために使われます。同様に、Service Workerは、active workerを「activated」として扱うのを、activateイベントのextend lifetime promises内のすべてのPromiseが決着(resolveまたはreject)するまで遅延します。(該当のActivateアルゴリズム手順を参照。)これは主に、ファンクショナルイベントがService Workerへ送信される前に、データベーススキーマのアップグレードや古いキャッシュエントリの削除が完了することを保証するために利用されます。

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. rules が RouterRule 辞書である場合、rules を « rules » に設定する。

  2. serviceWorker を current global object に関連付けられた service worker とする。

  3. rules の各 rule について:

    1. Verify Router Condition アルゴリズムを rule["condition"] および serviceWorker で実行した結果が false を返す場合、a promise rejected with a TypeError を返す。

    2. rule["source"] が "fetch-event" または "race-network-and-fetch-handler" のいずれかであり、かつ serviceWorker の set of event types to handle が fetch を contain しない場合、a promise rejected with a TypeError を返す。

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

  5. Add lifetime promise lifetimePromise を this に追加する。

    Note: event.addRoutes(rules) は、event.waitUntil(promise) が呼び出された場合と同様に、デフォルトでイベントの存続期間を延長する。

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

  7. promise が fulfillment または rejection したら、lifetimePromise を undefined で resolve する。

    Note: このステップは、install イベントの失敗を避けるために lifetimePromise を常に fulfilled にするためのものである。

  8. serviceWorkerEventLoop を current global object の event loop とする。

  9. 次の手順を [[service worker queue]] に Enqueue する:

    1. allRules を serviceWorker の list of router rules のコピーとする。

    2. rules の各 rule について:

      1. rule を allRules に追加する。

    3. Check Router Registration Limit を allRules で実行した結果が false を返す場合、次を実行する:

      1. task をキューに入れ、次の手順を serviceWorkerEventLoop 上で DOM manipulation task source を使用して実行する:

        1. promise を TypeError で reject する。

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

    4. serviceWorker の list of router rules を allRules に設定する。

    5. task をキューに入れ、次の手順を serviceWorkerEventLoop 上で DOM manipulation task source を使用して実行する:

      1. promise を undefined で resolve する。

  10. 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 イベントでは、ServiceWorker は FetchEvent インターフェースを利用し、これは 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 属性は、初期化時に設定された値を返すべきです。イベントが作成されたとき、この属性は空文字列に初期化すべきです。

注記: clientId は、リクエストに開始元となるサービスワーカー クライアントがある場合は、requestのクライアントのIDであり、それ以外の場合は空文字列である(例えば、開始元のない トップレベルのナビゲーションリクエスト)。ナビゲーションリクエストの結果として生じる文書に関連付けられた環境については、resultingClientId を参照すること。

4.6.4. event.resultingClientId

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

注記: resultingClientId は、requestの予約済みクライアントのIDである。サブリソースリクエストの場合、リクエストの宛先が"report" である場合、およびrequestの予約済みクライアントがnullである場合は、空文字列となる。

4.6.5. event.replacesClientId

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

4.6.6. event.handled

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

4.6.7. event.respondWith(r)

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

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

  1. event を this とする。

  2. event の dispatch flag が未設定なら、"InvalidStateError" DOMException をthrowする。

  3. event の respond-with entered flag が 設定済みなら、"InvalidStateError" DOMException をthrowする。

  4. lifetime promiseの追加 r を event に対して行う。

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

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

  6. event の respond-with entered flag を設定する。

  7. event の wait to respond flag を設定する。

  8. targetRealm を event の relevant Realm とする。

  9. rのrejection時:

    1. event の respond-with error flag を設定する。

    2. event の wait to respond flag を解除する。

  10. rのfulfillment時、response で:

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

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

    2. それ以外の場合:

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

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

      3. done をfalseとする。

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

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

        1. reader を reader取得 を response の body の stream で実行した結果とする。

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

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

            chunk steps(chunkを受け取る)
            1. アサート:chunk は Uint8Array である。

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

            3. potentialResponse の body info の encoded size を bytes の byte length だけ増加させる。

            4. potentialResponse の body info の decoded size を bytes の byte length だけ増加させる。

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

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

            error steps
            1. error newStream に TypeError を与える。

          2. read a chunk を reader に readRequest を与えて実行する。

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

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

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

        6. newStream を新しい ReadableStream とし、set up で pullAlgorithm pullAlgorithm、cancelAlgorithm cancelAlgorithm、highWaterMark highWaterMark、sizeAlgorithm sizeAlgorithm を targetRealm でセットアップする。

        7. potentialResponse の body を新しい body とし、その stream を newStream にする。

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

          1. newStream が errored なら、done をtrueにする。

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

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

            1. chunk を bytes の先頭からの部分列とする。

            2. chunk を bytes から除去する。

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

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

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

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

      6. event の potential response を potentialResponse に設定する。

    3. event の wait 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 = [];
};

各 ExtendableMessageEvent は origin(origin、文字列、または null)を持つ。初期値は null。

Service worker は extendable message イベントを定義し、イベントの存続期間を拡張可能にする。message イベントでは、service worker は ExtendableMessageEvent インターフェースを使用し、これは ExtendableEvent インターフェースを拡張している。

4.7.1. event.data

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

4.7.2. event.origin

origin属性は、メッセージを送信したサービスワーカー クライアントのオリジンを表す。

origin のゲッター手順:

  1. this の origin が origin型なら、 this の originのシリアル化を返す。

  2. this の origin が null なら空文字列を返す。

  3. this の origin を返す。

origin 属性が "初期化" されるとき(例えば ExtendableMessageEvent のコンストラクタ内など)、 初期化値はオブジェクトの origin に格納されます。

4.7.3. event.lastEventId

lastEventId 属性は、 初期化された値を返さなければならない (must)。オブジェクト生成時、この属性は 空文字列で初期化されなければならない (must)。

ExtendableMessageEvent インターフェースを実装するオブジェクトの extract an origin の手順は、 this の origin が origin 型であればその値を返し、そうでなければ null を返す。

4.7.4. event.source

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

4.7.5. event.ports

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

4.8. イベント

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

イベント名 インターフェイス カテゴリ 配送される場合…
install InstallEvent ライフサイクル サービスワーカーの包含サービスワーカー 登録のインストール中のワーカーが変更される。(インストール アルゴリズムの手順 11.2 を参照。)
activate ExtendableEvent ライフサイクル サービスワーカーの包含サービスワーカー 登録のアクティブワーカーが変更される。(アクティベート アルゴリズムの手順 12.2 を参照。)
fetch FetchEvent 機能 HTTP フェッチが request を用いてフェッチを処理するを 呼び出す。フェッチを処理するを実行した結果、サービスワーカーはHTTP フェッチにレスポンスを返す。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 ExtendableMessageEvent レガシー 逆シリアル化できないメッセージが送信された場合。

5. キャッシュ

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

5.1. 構成要素

リクエスト レスポンスリストは、リクエスト(リクエスト)およびレスポンス(レスポンス)からなるタプルのリストである。

関連リクエストレスポンスリストは、これが表すインスタンスである。

名前からキャッシュへの マップは、そのエントリーが、キー (リクエストレスポンスリストの名前を表す文字列)および値(リクエストレスポンスリスト)からなる順序付きマップである。

CacheStorage オブジェクトの関連する名前からキャッシュへのマップは、そのオブジェクトの関連設定オブジェクトおよび「caches」を用いてローカルストレージボトルマップを取得するを実行した結果に関連付けられた名前からキャッシュへのマップである。

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. p を matchAll(request, options) メソッド(requestとoptionsを渡す)で実行したアルゴリズムの結果とする。

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

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

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

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

      1. responses が空配列の場合:

        1. promise をundefinedでresolveする。

      2. それ以外の場合:

        1. promise をresponsesの最初の要素でresolveする。

  3. promise を返す。

5.4.2. matchAll(request, options)

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

  1. r を null とする。

  2. 省略可能な引数 request が省略されていない場合:

    1. request が Request オブジェクトである場合:

      1. r を request の リクエストに設定する。

      2. r の メソッドが `GET` ではなく、かつ options.ignoreMethod が false である場合、空の配列で 解決された promiseを 返す。

    2. それ以外で、request が文字列である場合:

      1. request を引数として Request の初期値をコンストラクターとして呼び出した結果に関連付けられた リクエストを r に設定する。これが例外を スローする場合、その例外を伴う 拒否された promiseを 返す。

  3. realm を this の 関連するレルムとする。

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

  5. 次のサブステップを 並行に実行する:

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

    2. 省略可能な引数 request が省略されている場合:

      1. 各 requestResponse (関連するリクエスト レスポンスリスト内)について:

        1. requestResponse の response のコピーを responses に追加する。

    3. それ以外の場合:

      1. r および options を用いて Query Cache を実行した結果を requestResponses とする。

      2. requestResponses の 各 requestResponse について:

        1. requestResponse の response のコピーを responses に追加する。

    4. 各 responses の response について:

      1. response の type が "opaque" であり、promise の relevant settings object の origin、 promise の relevant settings object、""、および response の internal response を用いた cross-origin resource policy check が blocked を返す場合、promise を TypeError で reject し、これらの手順を中止する。

    5. task をキューに入れ、promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、次の手順を実行する:

      1. responseList を list とする。

      2. 各 responses の response について:

        1. response に関連付けられた新しい Response オブジェクトと、guard が "immutable" である新しい Headers オブジェクトを responseList に追加する。

      3. realm 内で、responseList から created された frozen array で promise を resolve する。

  6. promise を返す。

5.4.3. add(request)

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

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

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

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

5.4.4. addAll(requests)

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

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

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

  3. requests 内の型が Request である各 request について:

    1. r を request の リクエストとする。

    2. r の URL の スキームが "http" および "https" のいずれでもない場合、または r の メソッドが `GET` でない場合、 TypeError を伴う 拒否された promiseを 返す。

  4. fetchControllers を フェッチコントローラーの リストとする。

  5. requests 内の各 request について:

    1. request を引数として Request の初期値をコンストラクターとして呼び出した結果に関連付けられた リクエストを r とする。これが例外を スローする場合、その例外を伴う 拒否された promiseを 返す。

    2. r の URL の スキームが "http" および "https" のいずれでもない場合:

      1. fetchControllers の各 fetchController に ついて、fetchController を 中止する。

      2. TypeError を伴う 拒否された promiseを 返す。

    3. r の クライアントの グローバルオブジェクトが ServiceWorkerGlobalScope オブジェクトである場合、request の service-workers モードを "none" に設定する。

    4. r を requestList に追加する。

    5. responsePromise を 新しい promiseとする。

    6. 次のサブステップを 並行に実行する:

      • r を フェッチした結果を 付加する。

      • response に対して processResponse を行うには、 次のサブステップを実行する:

        1. response の 型が "error" である場合、または response の ステータスが ok ステータスでないか、206 である場合、 responsePromise を TypeError で拒否する。

        2. それ以外で、response の ヘッダーリストが、 名前が `Vary` である ヘッダーを含む場合:

          1. fieldValues を、Vary ヘッダーの フィールド値に対応する要素を含む リストとする。

          2. fieldValues の各 fieldValue に ついて:

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

              1. responsePromise を TypeError で拒否する。

              2. fetchControllers の各 fetchController に ついて、fetchController を 中止する。

              3. これらのステップを中止する。

      • response に対して processResponseEndOfBody を行うには、次のサブステップを実行する:

        1. response の 中止済みフラグが 設定されている場合、responsePromise を "AbortError" DOMException で拒否し、これらのステップを中止する。

        2. responsePromise を response で解決する。

        注: キャッシュへの コミットは、レスポンスの本体を完全に受信したときに許可される。

    7. responsePromise を responsePromises に追加する。

  6. p を、responsePromises のすべてを 待機する promise を取得した結果と する。

  7. p に対して、引数 responses で呼び出されたときに 次のサブステップを実行する履行ハンドラーを使用して 反応した結果を返す:

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

    2. index をゼロとする。

    3. responses 内の各 response について:

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

      2. operation の 型を "put" に設定する。

      3. operation の リクエストを requestList[index] に設定する。

      4. operation の レスポンスを response に設定する。

      5. operation を operations に 付加する。

      6. index を 1 増加させる。

    4. realm を this の 関連するレルムとする。

    5. cacheJobPromise を 新しい promiseとする。

    6. 次のサブステップを 並行に実行する:

      1. errorData を null とする。

      2. Batch Cache Operations を operations で呼び出す。これが throws で例外を投げる場合、 errorData をその例外に設定する。

      3. task をキューに入れ、cacheJobPromise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、次のサブステップを実行する:

        1. errorData が null の場合、 cacheJobPromise を undefined で resolve する。

        2. それ以外の場合、realm 内で errorData を使った new exception で cacheJobPromise を reject する。

    7. cacheJobPromise を返す。

5.4.5. put(request, response)

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

  1. innerRequest を null とする。

  2. request が Request オブジェクトである場合、innerRequest を request の リクエストに設定する。

  3. それ以外の場合:

    1. request を引数として Request の コンストラクターを呼び出した結果を requestObj とする。これが exception を スローする場合、exception で 拒否された promiseを返す。

    2. innerRequest を requestObj の リクエストに設定する。

  4. innerRequest の URL の スキームが "http" および "https" のいずれでもない場合、または innerRequest の メソッドが `GET` でない場合、TypeError で拒否された promiseを 返す。

  5. innerResponse を response の レスポンスとする。

  6. innerResponse の ステータスが 206 である場合、TypeError で拒否された promiseを 返す。

  7. innerResponse の ヘッダーリストが、ヘッダーのうち、名前が `Vary` であるものを含む場合:

    1. fieldValues を、Vary ヘッダーの フィールド値に対応する 項目を含む リスト とする。

    2. fieldValues 内の各 fieldValue に ついて:

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

  8. innerResponse の 本体が 攪乱されているか、または ロックされている場合、TypeError で拒否された promiseを 返す。

  9. clonedResponse を innerResponse の クローンとする。

  10. bodyReadPromise を undefined で 解決された promiseとする。

  11. innerResponse の 本体が null でない場合、次のサブステップを実行する:

    1. stream を innerResponse の 本体の ストリームとする。

    2. reader を stream の リーダーを取得した結果と する。

    3. bodyReadPromise を、reader から すべての バイトを読み取った結果に設定する。

    注: これにより、 innerResponse の 本体が ロックされ、本体の完全にバッファリングされたコピーが clonedResponse に保持されることが保証される。実装は、メモリーではなく ディスクへ直接ストリーミングすることで最適化できる。

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

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

  14. operation の 型を "put" に設定する。

  15. operation の リクエストを innerRequest に設定する。

  16. operation の レスポンスを clonedResponse に設定する。

  17. operation を operations に 付加する。

  18. realm を this の 関連するレルムとする。

  19. bodyReadPromise の 履行時に、次の結果を返す:

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

    2. cacheJobPromise を返し、次のステップを 並行に実行する:

      1. errorData を null とする。

      2. Batch Cache Operations を operations で呼び出す。これが throws で例外を投げる場合、 errorData をその例外に設定する。

      3. task をキューに入れ、cacheJobPromise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、次のサブステップを実行する:

        1. errorData が null の場合、 cacheJobPromise を undefined で resolve する。

        2. それ以外の場合、realm 内で errorData を使った new exception で cacheJobPromise を reject する。

5.4.6. delete(request, options)

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

  1. r を null とする。

  2. request が Request オブジェクトである場合:

    1. r を request の リクエストに設定する。

    2. r の メソッドが `GET` ではなく、かつ options.ignoreMethod が false である場合、false で 解決された promiseを返す。

  3. それ以外で、request が文字列である場合:

    1. request を引数として Request の初期値をコンストラクターとして呼び出した結果に関連付けられた リクエストを r に設定する。これが例外を スローする場合、その例外を伴う 拒否された promiseを 返す。

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

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

  6. operation の 型を "delete" に設定する。

  7. operation の リクエストを r に設定する。

  8. operation の オプションを options に設定する。

  9. operation を operations に 付加する。

  10. realm を this の 関連するレルムとする。

  11. cacheJobPromise を 新しい promiseとする。

  12. 次のサブステップを 並行に実行する:

    1. errorData を null とする。

    2. operations を用いて キャッシュ 操作を一括処理を実行した結果を requestResponses とする。これが例外を スローする場合、errorData をその例外に設定する。

    3. task をキューに入れ、cacheJobPromise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、次のサブステップを実行する:

      1. errorData が null である場合:

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

        2. それ以外の場合、cacheJobPromise を false で解決する。

      2. それ以外の場合、realm 内で、errorData を伴う 新しい 例外によって cacheJobPromise を拒否する。

  13. cacheJobPromise を返す。

5.4.7. keys(request, options)

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

  1. r を null とする。

  2. 省略可能な引数 request が省略されていない場合:

    1. request が Request オブジェクトである場合:

      1. r を request の リクエストに設定する。

      2. r の メソッドが `GET` ではなく、かつ options.ignoreMethod が false である場合、空の配列で 解決された promiseを 返す。

    2. それ以外で、request が文字列である場合:

      1. request を引数として Request の初期値をコンストラクターとして呼び出した結果に関連付けられた リクエストを r に設定する。これが例外を スローする場合、その例外を伴う 拒否された promiseを 返す。

  3. realm を this の 関連するレルムとする。

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

  5. 次のサブステップを 並行に実行する:

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

    2. 省略可能な引数 request が省略されている場合:

      1. 各 requestResponse (関連するリクエスト レスポンスリスト内)について:

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

    3. それ以外の場合:

      1. r および options を用いて Query Cache を実行した結果を requestResponses とする。

      2. requestResponses の 各 requestResponse について:

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

    4. task をキューに入れ、promise の relevant settings object の responsible event loop 上で、DOM manipulation task source を使用して、次の手順を実行する:

      1. requestList を リストとする。

      2. requests の 各 request について:

        1. request および、ガードが "immutable" である新しい関連付けられた Headers オブジェクトに関連付けられた新しい Request オブジェクトを requestList に追加する。

      3. realm 内で、requestList から 作成された 凍結配列を用いて promise を解決する。

  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オブジェクトに準拠するよう設計されていますが、すべて非同期であり、さらに便利なメソッドも備えています。clear、forEach、entries、valuesの各メソッドは、TC39による非同期イテレーションについての議論が継続中であるため、初版の範囲からは意図的に除外されています。

ユーザーエージェントは、CacheStorage オブジェクトをWindow オブジェクトまたはWorkerGlobalScope オブジェクトが作成された際に必ず作成しなければなりません。

CacheStorage オブジェクトは、そのname to cache mapを、自身の関連設定オブジェクトと"caches"を使ってローカルストレージボトルマップを取得した結果に紐付けて表現します。ドキュメントやワーカーをまたいでCacheStorage インターフェースの複数の独立したオブジェクトが、同じname to cache mapに同時に紐付くことができます。

5.5.1. match(request, options)

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

  1. もしoptions["cacheName"] が存在する場合、次を実行:

    1. 新しいPromise promise を返し、以下のサブステップを並列で実行する:

      1. 各 cacheName → cache について、relevant name to cache map を反復する:

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

          1. promise を、Cache インターフェースの match(request, options) メソッド(thisArgumentに cache を与えて \[[Call]] 内部メソッドで match(request, options) を呼び出し)をrequestとoptionsで実行した結果でresolveする。

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

      2. promiseをundefinedでresolveする。

  2. それ以外の場合:

    1. promise に undefinedでresolveされたpromise を設定する。

    2. 各 cacheName → cache について、relevant name to cache map を反復する:

      1. promise を自身の決着に反応する形で、 fulfillment handlerとして以下のサブステップを実行する形に設定する。引数はresponseとする:

        1. もしresponseがundefinedでなければ、そのresponseを返す。

        2. Cache インターフェースの match(request, options) メソッド(thisArgumentに cache を与えて \[[Call]] 内部メソッドで match(request, options) を呼び出し)をrequestとoptionsで実行した結果を返す。

    3. promiseを返す。

5.5.2. has(cacheName)

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

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

  2. 次のサブステップを並列で実行する:

    1. 各 key → value について、relevant name to cache map を反復する:

      1. もしcacheNameがkeyと一致したら、promiseをtrueで解決し、これらの手順を中止する。

    2. promiseをfalseで解決する。

  3. promiseを返す。

5.5.3. open(cacheName)

open(cacheName)メソッドの手順は次の通り:

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

  2. 次のサブステップを並列で実行する:

    1. 各key→valueについて、relevant name to cache mapを反復する:

      1. もしcacheNameがkeyと一致するなら:

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

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

    2. cacheを新しいrequest response listとする。

    3. Setを使い、relevant name to cache map[cacheName]にcacheを設定する。このキャッシュ書き込み操作が割り当てられたクォータ制限超過で失敗した場合、promiseをQuotaExceededErrorでrejectし、これらの手順を中止する。

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

  3. promiseを返す。

5.5.4. delete(cacheName)

delete(cacheName)メソッドの手順は次の通り:

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

  2. promiseの決着に反応する形で、 fulfillment handlerを以下の通り実行した結果を返す。引数はcacheExistsとする:

    1. もしcacheExistsがfalseなら:

      1. falseを返す。

    2. cacheJobPromiseを新しいPromiseとする。

    3. 次のサブステップを並列で実行する:

      1. Removeを使い、relevant name to cache map[cacheName]を削除する。

      2. cacheJobPromiseをtrueでresolveする。

      注: このステップの後でも、既存のDOMオブジェクト(つまり参照されているCache、Request、Responseオブジェクト)は引き続き有効であるべきです。

    4. cacheJobPromiseを返す。

5.5.5. keys()

keys()メソッドの手順は次の通り:

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

  2. 次のサブステップを並列で実行する:

    1. cacheKeysを relevant name to cache mapのキー取得の結果とする。

      注: 結果の順序付き集合内の各項目は、name to cache mapに追加された順序となる。

    2. promiseをcacheKeysでresolveする。

  3. promiseを返す。

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

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

サービス ワーカーは、セキュアコンテキストで実行されなければならない。サービスワーカー クライアントも、サービス ワーカー登録を登録し、サービス ワーカー登録およびサービスワーカーにアクセスし、サービス ワーカーとメッセージを交換し、さらにサービスワーカーによって操作されるためには、セキュアコンテキストでなければならない。

注記: これは実質的に、サービス ワーカーおよびそのサービスワーカークライアントを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. serviceWorkerを、requestのクライアントのグローバルオブジェクトのサービスワーカーとする。

  2. map を serviceWorker の スクリプトリソースマップ とする。

  3. url を request の url とする。

  4. serviceWorker の state が "parsed" または "installing" でない場合:

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

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

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

    2. map[url] を返す。

  6. registration を serviceWorker の ServiceWorker登録 とする。

  7. request の service-workers mode を "none" に設定する。

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

  9. response を requestのfetch結果とする。

  10. response の cache state が "local" でない場合、registration の last update check time を現在時刻に設定する。

  11. response の unsafe response が bad 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できます。 Service Workerは、Cachesがオフオリジンのアイテムをフェッチしてキャッシュできるようにすることで、これを実現します。ただし、いくつかの制約があります。まず、Cache内で管理される同一オリジンリソースと異なり、対応するレスポンスがbasic filtered responseであるResponseオブジェクトとは違い、保存されるオブジェクトは、対応するレスポンスがCORSフィルタされたレスポンスまたはopaque filtered responseとなるResponseオブジェクトです。これらは、対応するレスポンスがbasic filtered responseとなるResponseオブジェクトと同じ方法でevent.respondWith(r) メソッドに渡すことができますが、プログラム的に意味のある方法で生成することはできません。これらの制限はプラットフォームのセキュリティ不変条件を維持するために必要です。Caches がこれらを保存可能なことにより、多くの場合アプリケーション側での大きな設計変更を避けることができます。

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. プライバシー

Service Workerは、新しい永続ストレージ機能を導入します。これには、registration map(Service Workerの登録やそのService Worker用)、request response listやname to cache map(キャッシュ用)、そしてscript resource map(スクリプトリソース用)が含まれます。ユーザーを許可されていないトラッキングの脅威から守るため、これらの永続ストレージは、ユーザーが消去しようと意図したとき消去されるべきであり、また、既存のユーザーコントロール(例:全ての永続ストレージの消去)と整合し、相互運用すべきです。

7. 拡張性

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

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

仕様は、Service Worker 登録に紐付いたAPIを、partial interface定義を用いてServiceWorkerRegistrationインターフェイスに属性やメソッドを仕様ごとに定義してもよい。

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リクエストの抽象化です。

ジョブはジョブタイプ(register、update、unregisterのいずれか)を持ちます。

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

ジョブはscope url(URL)を持ちます。

ジョブはスクリプトurl(URL)を持ちます。

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

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

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

ジョブはreferrer(URLまたはnull)を持ちます。

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

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

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

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

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

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

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

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

race resultは、タプルであり、routed responseとused routeから構成されます。

race resultは、関連付けられたrouted response(response)を持ちます。

race resultは、関連付けられたused route(RouterSourceEnum)を持ちます。

ジョブの作成

入力

jobType:ジョブタイプ

storage key:ストレージキー

scopeURL:URL

scriptURL:URL

promise:promise

client:ServiceWorkerクライアント

出力

job:ジョブ

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

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

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

  4. job の scope url を scopeURL に設定する。

  5. job の script url を scriptURL に設定する。

  6. job の ジョブpromise を promise に設定する。

  7. job の client を client に設定する。

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

  9. job を返す。

ジョブのスケジュール

入力

job:ジョブ

出力

なし

  1. jobQueue を null とする。

  2. jobScope を job の scope url(シリアライズ済み)とする。

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

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

  5. jobQueue が空なら:

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

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

  6. そうでない場合:

    1. lastJob を jobQueue の末尾要素とする。

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

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

ジョブの実行

入力

jobQueue:ジョブキュー

出力

なし

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

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

    1. job を jobQueue の最初の item とする。

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

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

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

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

ジョブの完了

入力

job:ジョブ

出力

なし

  1. jobQueue を job の 所属ジョブキュー に設定する。

  2. アサート:jobQueue の最初の item が job である。

  3. dequeue を jobQueue から実行する。

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

ジョブpromiseの解決

入力

job:ジョブ

value:任意

出力

なし

  1. job の client が null でない場合、task をキューに入れ、job の client の responsible event loop 上で、DOM manipulation task source を使用して、次の サブステップを実行する:

    1. convertedValue を null とする。

    2. job の job type が register または update のいずれかである場合、convertedValue を、value を job の client で表す service worker registration object の取得 の結果に設定する。

    3. それ以外の場合、convertedValue を value に、job の client の Realm 内で設定する。

    4. job の job promise を convertedValue で resolve する。

  2. job の list of equivalent jobs 内の各 equivalentJob について:

    1. equivalentJob の client が null の場合、ループの次の反復に continue する。

    2. task をキューに入れ、equivalentJob の client の responsible event loop 上で、DOM manipulation task source を使用して、 次のサブステップを実行する:

      1. convertedValue を null とする。

      2. equivalentJob の job type が register または update のいずれかである場合、convertedValue を、value を equivalentJob の client で表す service worker registration object の取得 の結果に設定する。

      3. それ以外の場合、convertedValue を value に、 equivalentJob の client の Realm 内で設定する。

      4. equivalentJob の job promise を convertedValue で resolve する。

ジョブpromiseの拒否

入力

job:ジョブ

errorData:例外生成に必要な情報

出力

なし

  1. job のクライアントが null でない場合、job のクライアントの 担当イベントループ上で、DOM 操作タスクソースを使用して、タスクをキューに入れ、job のジョブプロミスを、job のクライアントのRealm内で、errorData を持つ新しい例外で拒否する。

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

    1. equivalentJob のクライアントが null の場合、続行する。

    2. equivalentJob のクライアントの担当イベントループ上で、DOM 操作タスクソースを使用して、タスクをキューに入れ、equivalentJob のジョブプロミスを、equivalentJob のクライアントのRealm内で、 errorData を持つ新しい例外で拒否する。

登録開始

入力

scopeURL:URL/失敗/null

scriptURL:URL/失敗

promise:promise

client:ServiceWorkerクライアント

referrer:URL

workerType:ワーカータイプ

updateViaCache:update via cache mode

出力

なし

  1. scriptURL が失敗なら、promise を TypeError でrejectし、これらの手順を中止する。

  2. scriptURL の fragment を null に設定する。

    注: ユーザーエージェントはスクリプトurlの fragment を保存しません。つまりfragmentはServiceWorkerの識別には影響しません。

  3. scriptURL の scheme が "http"/"https" 以外なら、promise を TypeError でrejectし、これらの手順を中止する。

  4. scriptURL の path 内のいずれかに ASCII大文字小文字無視 "%2f" または ASCII大文字小文字無視 "%5c" が含まれるなら、promise を TypeError でrejectし、これらの手順を中止する。

  5. scopeURL が null なら、scopeURL を "./" を scriptURL でパースした結果に設定する。

    注: 登録のscope urlはデフォルトでServiceWorkerスクリプトの場所になります。

  6. scopeURL が失敗なら、promise を TypeError でrejectし、これらの手順を中止する。

  7. scopeURL の fragment を null に設定する。

    注: ユーザーエージェントはscope urlの fragment を保存しません。つまりfragmentはServiceWorker登録の識別には影響しません。

  8. scopeURL の scheme が "http"/"https" 以外なら、promise を TypeError でrejectし、これらの手順を中止する。

  9. scopeURL の path 内のいずれかに ASCII大文字小文字無視 "%2f" または ASCII大文字小文字無視 "%5c" が含まれるなら、promise を TypeError でrejectし、これらの手順を中止する。

  10. storage key を clientからストレージキー取得 の結果とする。

  11. job を Create Job(register、storage key、scopeURL、scriptURL、promise、client)の結果とする。

  12. job の worker type を workerType に設定する。

  13. job の update via cache mode を updateViaCache に設定する。

  14. job の referrer を referrer に設定する。

  15. ジョブのスケジュール(job)を呼び出す。

登録

入力

job:ジョブ

出力

なし

  1. potentially trustworthy origin(job の script urlのorigin)の結果が Not Trusted なら:

    1. ジョブpromiseの拒否(job、"SecurityError" DOMException)を呼び出す。

    2. ジョブの完了(job)を呼び出し、これらの手順を中止する。

  2. job の script url の origin と job の referrer の origin が 同一オリジンでなければ:

    1. ジョブpromiseの拒否(job、"SecurityError" DOMException)を呼び出す。

    2. ジョブの完了(job)を呼び出し、これらの手順を中止する。

  3. job の scope url の origin と job の referrer の origin が 同一オリジンでなければ:

    1. ジョブpromiseの拒否(job、"SecurityError" DOMException)を呼び出す。

    2. ジョブの完了(job)を呼び出し、これらの手順を中止する。

  4. registration を Get Registration(job の ストレージキー、job の scope url)の結果とする。

  5. registration が null でなければ:

    1. newestWorker を Get Newest Worker(registration)の結果とする。

    2. newestWorker が null でなく、job の script url が newestWorkerのscript urlと一致、job の worker type が newestWorkerのtypeと一致、job の update via cache mode が registrationのupdate via cache modeと一致するなら:

      1. ジョブpromiseの解決(job、registration)を呼び出す。

      2. ジョブの完了(job)を呼び出し、これらの手順を中止する。

  6. それ以外:

    1. Set Registration(job の ストレージキー、job の scope url、job の update via cache mode)アルゴリズムを呼び出す。

  7. Update(job)アルゴリズムを呼び出す。

更新

入力

job:ジョブ

出力

なし

  1. registration を Get Registration(job の ストレージキー、job の scope url)の結果とする。

  2. registration が null なら:

    1. ジョブpromiseの拒否(job、TypeError)を呼び出す。

    2. ジョブの完了(job)を呼び出し、これらの手順を中止する。

  3. newestWorker を Get Newest Worker(registration)の結果とする。

  4. job の ジョブタイプ が update かつ newestWorker が null でなく、かつ newestWorker の script url が jobのscript urlと一致しないなら:

    1. ジョブpromiseの拒否(job、TypeError)を呼び出す。

    2. ジョブの完了(job)を呼び出し、これらの手順を中止する。

  5. hasUpdatedResources を false とする。

  6. updatedResourceMap を 順序付きマップ(キー:URL、値:response)とする。

  7. job の worker type に応じて以下のオプションでサブステップを実行:

    "classic"

    クラシックワーカースクリプトのfetch(job の シリアライズ済み script url、job の client、"serviceworker"、このServiceWorker用の生成予定environment settings object)を呼び出す。

    "module"

    モジュールワーカースクリプトグラフのfetch(job の シリアライズ済み script url、job の client、"serviceworker"、"same-origin"、このServiceWorker用の生成予定environment settings object)を呼び出す。

    具体的な環境設定オブジェクトではなく、生成予定の環境設定オブジェクトを利用しています。これは、Service Workerが他のWeb Workerと比べて独自の処理モデルを持つためです。HTML標準で他のWeb Worker向けに設計されたスクリプト取得アルゴリズムでは、実行環境の環境設定オブジェクトが必要ですが、Service Workerでは、Updateアルゴリズムでスクリプトを個別に取得し、その後Run Service Workerアルゴリズムを通じてスクリプトが複数回実行される前処理が行われます。

    HTMLのクラシックワーカースクリプトをフェッチするアルゴリズムとモジュールワーカースクリプトグラフをフェッチするアルゴリズムはjob の clientを引数に取るが、job の clientはSoft Updateアルゴリズムから呼ぶときnull。

    fetchフック(request)の実行手順:

    1. `Service-Worker`/`script` を request の ヘッダーリストに追加する。

      注: Service-Workerヘッダーの定義は付録B: 拡張HTTPヘッダーを参照。

    2. 下記のいずれかが真であれば、request の cache mode を "no-cache" に設定する:

      注: cache mode が "no-cache" でなくても、ユーザーエージェントはネットワーク層でCache-Controlヘッダーのmax-age値に従い、ブラウザキャッシュをバイパスすべきかを判断する。

    3. request の service-workers mode を "none" に設定する。

    4. もし isTopLevel フラグが未設定なら、fetch で request を取得した結果を返す。

    5. request の redirect mode を "error" に設定する。

    6. Fetch で request を取得し、fetch の processResponse の一部として、残りのステップを非同期に待つ。response は response。

    7. response の ヘッダーリスト から MIME type を抽出。このMIMEタイプ(パラメータを無視)が JavaScript MIME type でなければ:

      1. Reject Job Promise を job と "SecurityError" DOMException で呼び出す。

      2. 非同期でこれらのステップをnetwork errorとして完了する。

    8. serviceWorkerAllowed を、response の ヘッダーリストから取得する `Service-Worker-Allowed` の結果とする。ヘッダーリスト。

      注: Service-Worker-Allowed ヘッダーの定義は、 付録 B: 拡張 HTTP ヘッダーを参照。

    9. serviceWorkerAllowed が null でない場合、 serviceWorkerAllowed を 同型デコード の結果に設定する。 serviceWorkerAllowed。

    10. policyContainer を、response を指定して実行した fetch レスポンスから ポリシーコンテナーを作成する結果に設定する。

    11. scopeURL を registration の スコープ URL とする。

    12. maxScopeString を null とする。

    13. serviceWorkerAllowed が null の場合:

      1. resolvedScope を、job の スクリプト URL を ベース URL として "./" を 解析する結果とする。

      2. maxScopeString を "/" に設定し、その後に resolvedScope の パス 内の文字列(空文字列を含む)を "/" で区切って続ける。

        注: resolvedScope の パス の最後の項目は常に空文字列になるため、 maxScopeString には末尾の "/" が付く。

    14. それ以外の場合:

      1. maxScope を、job の スクリプト URL を ベース URL として serviceWorkerAllowed を 解析する結果とする。

      2. maxScope が失敗の場合:

        1. これらの手順を ネットワークエラーで非同期に完了する。

      3. maxScope の オリジン が、job の スクリプト URL の オリジン である場合:

        1. maxScopeString を "/" に設定し、その後に maxScope の パス 内の文字列(空文字列を含む)を "/" で区切って続ける。

    15. scopeString を "/" とし、その後に scopeURL の パス 内の文字列(空文字列を含む)を "/" で区切って続ける。

    16. maxScopeString が null、または scopeString が maxScopeString で始まらない場合:

      1. job と "SecurityError" DOMException を指定して Reject Job Promise を呼び出す。

      2. これらの手順を ネットワークエラーで非同期に完了する。

    17. url を request の URL とする。

    18. updatedResourceMap[url] を response に設定する。

    19. response の キャッシュ状態 が "local" でない場合、registration の 最終 更新確認時刻 を現在時刻に設定する。

    20. 次のいずれかが true の場合、hasUpdatedResources を true に設定する:

    21. hasUpdatedResources が false であり、かつ newestWorker の クラシックスクリプトインポート済み フラグ が設定されている場合:

      注: 以下では、 メインスクリプトが変更されていないため、インポートされたスクリプトが更新されたかを確認する。

      1. newestWorker の スクリプトリソースマップ の 各 importUrl → storedResponse について 反復する:

        1. importUrl が url である場合、続行する。

        2. importRequestを、リクエストであって、そのURLが importUrl、クライアントが jobのクライアント、宛先が 「script」、パーサーメタデータが 「not parser-inserted」であり、そのURL資格情報使用 フラグが設定された、新しいリクエストとする。

        3. 次のいずれかが true の場合、importRequest の キャッシュモード を "no-cache" に設定する:

        4. fetchedResponse を、importRequest を fetch する結果とする。

        5. updatedResourceMap[importRequest の URL] を fetchedResponse に設定する。

        6. fetchedResponse を fetchedResponse の 安全でないレスポンス に設定する。

        7. fetchedResponse の キャッシュ状態 が "local" でない場合、registration の 最終更新確認 時刻 を現在時刻に設定する。

        8. fetchedResponse が 不正なインポートスクリプト レスポンス である場合、続行する。

          注: importScripts() に対する不正な レスポンスは、バイト単位のチェックの目的では無視される。現在のワーカーに対する良好な レスポンスと、潜在的な更新ワーカーに対する良好なレスポンスのみが考慮される。根拠については issue #1374 を参照。

        9. fetchedResponse の 本文 が、 storedResponse の 安全でないレスポンス の 本文 とバイト単位で同一でない場合、 hasUpdatedResources を true に設定する。

          注: キャッシュにデータを投入するため、すべてのインポートされたスクリプトについて続行するので、 このステップでは制御はループを中断しない。

    22. 非同期でこれらのステップを response で完了する。

    アルゴリズムが非同期完了したら、残りの手順をscript(非同期完了値)で続行。

  8. もし script が null または Is Async Module を script の record、script の base URL、および « » を与えて実行した結果が true なら:

    1. Reject Job Promise を job と TypeError で呼び出す。

      注: すでに Reject Job Promise が "SecurityError DOMException" で呼び出されていた場合、ここでは何もしない。

    2. もし newestWorker が null なら、 registration map[(registration の storage key、serialized scopeURL)] を削除する。

    3. Finish Job を job で呼び出し、これらの手順を中止する。

  9. もし hasUpdatedResources が false なら:

    1. registration の update via cache mode に job の update via cache mode を設定する。

    2. Resolve Job Promise を job と registration で呼び出す。

    3. Finish Job を job で呼び出し、これらの手順を中止する。

  10. worker を新しい service worker とする。

  11. worker の script url に job の script url、worker の script resource に script、worker の type に job の worker type、および worker の script resource map に updatedResourceMap を設定する。

  12. url を worker の set of used scripts に追加する。

  13. worker の script resource の policy container に policyContainer を設定する。

  14. forceBypassCache に、job の force bypass cache flag がセットされていれば true、そうでなければ false を設定する。

  15. runResult を Run Service Worker アルゴリズムに worker と forceBypassCache を与えて実行した結果とする。

  16. もし runResult が failure または abrupt completion なら:

    1. Reject Job Promise を job と TypeError で呼び出す。

    2. もし newestWorker が null なら、 registration map[(registration の storage key、serialized scopeURL)] を削除する。

    3. Finish Job を job で呼び出す。

  17. それ以外の場合は、Install アルゴリズムを job、worker、registration で実行する。

ソフトアップデート

ユーザーエージェントは好きな頻度で呼び出してアップデートを確認してもよい。

入力

registration:ServiceWorker登録

forceBypassCache:オプションのboolean。デフォルトはfalse。

注: 実装者はforceBypassCacheをデバッグ用途(開発者ツールなど)や、ServiceWorker拡張仕様で任意に利用してもよい。

出力

なし

  1. newestWorker を Get Newest Worker(registration)の結果とする。

  2. newestWorker が null なら、これらの手順を中止する。

  3. job を Create Job(update、registration の ストレージキー、registration の scope url、newestWorker の script url、null、null)で生成。

  4. job の worker type を newestWorker の type に設定する。

  5. forceBypassCache が true なら job の force bypass cache flag を設定する。

  6. ジョブのスケジュール(job)を呼び出す。

ソフト更新を 要求

このアルゴリズムにより、他の仕様はユーザーエージェントに対して、サービスワーカー登録の更新を確認するよう要求できます。

入力

registration、サービスワーカー登録

requestingStorageKey、ストレージ キー

forceBypassCache、省略可能な真偽値。既定値は false

出力

なし

  1. registrationのストレージキーが requestingStorageKeyと等しくない場合、return する。

  2. ユーザーエージェントが registration の更新確認の頻度を制限すると 判断した場合、return する。

    注: ユーザーエージェントは、更新確認の頻度を 制限すること、または短い間隔で発生する registration に対する複数回の呼び出しを 1 回の呼び出しとして扱うことにより、過剰なリソース使用を防ぐことができます。呼び出し元は、 このアルゴリズムによって更新確認が行われることに依存できません。

  3. registration と forceBypassCache を指定して、ソフト更新 アルゴリズムを実行する。

注: 呼び出し元の仕様は、その要求に関連付けられた ストレージキーを提供する責任があります。

インストール

入力

job:ジョブ

worker:ServiceWorker

registration:ServiceWorker登録

出力

なし

  1. installFailed を false とする。

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

  3. registration のキャッシュ経由更新モードを job のキャッシュ経由更新モードに設定する。

  4. registration、"installing"、worker を引数として渡して、登録状態を更新アルゴリズムを 実行する。

  5. registration のインストール中のワーカーと "installing" を引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

  6. 表明:job のジョブプロミスは null ではない。

  7. job と registration を指定してジョブプロミスを解決を呼び出す。

  8. settingsObjects を、そのオリジンが registration のスコープ URLの オリジンである、すべての環境設定オブジェクトとする。

  9. settingsObjects の各 settingsObject について、settingsObject の担当イベントループ上で、DOM 操作タスクソースにおいて、次の 手順を実行するタスクをキューに入れる:

    1. registrationObjects を、settingsObject のRealm内にあるすべての ServiceWorkerRegistration オブジェクトのうち、そのサービス ワーカー登録が registration であるものとする。

    2. registrationObjects の各 registrationObject について、 registrationObject 上で updatefound という名前のイベントを発火する。

  10. installingWorker を registration のインストール中のワーカーとする。

  11. installingWorker と "install" を指定してイベントをスキップすべきかアルゴリズムを実行した結果が false の場合、次を行う:

    1. forceBypassCache を、job のキャッシュを強制的にバイパスするフラグが 設定されている場合は true、それ以外の場合は false とする。

    2. installingWorker と forceBypassCache を指定してサービスワーカーを実行アルゴリズムを実行した結果が失敗の場合、 次を行う:

      1. installFailed を true に設定する。

    3. それ以外の場合:

      1. installingWorker のイベントループ上で、DOM 操作タスク ソースを使用して、次の手順を実行するタスク task をキューに入れる:

        1. e を、InstallEvent を用いてイベントを作成した結果とする。

        2. e の type 属性を install に初期化する。

        3. installingWorker のグローバル オブジェクトに e を配送する。

        4. 非同期拡張を待機:次の副手順を並列に実行する:

          1. e がアクティブでなくなるまで 待機する。

          2. e のタイムアウト フラグが設定されている場合、installFailed を true に設定する。

          3. p を、e のライフタイムを 延長するプロミスのすべてを待機するためのプロミスを取得した結果とする。

          4. p が拒否されたとき、installFailed を true に設定する。

        task が破棄された場合、installFailed を true に設定する。

      2. task が実行されるか、破棄されるまで待機する。

      3. 非同期拡張を待機とラベル付けされた手順が完了するまで待機する。

  12. installFailed が true の場合、次を行う:

    1. registration のインストール中のワーカーと "redundant" を引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

    2. registration、"installing"、null を 引数として渡して、登録状態を更新アルゴリズムを実行する。

    3. newestWorker が null の場合、登録 マップ[(registration のストレージキー, 直列化された registration の スコープ URL)] を削除する。

    4. job を指定してジョブを 完了を呼び出し、これらの手順を中止する。

  13. map を registration のインストール中の ワーカーのスクリプトリソースマップとする。

  14. usedSet を registration のインストール中の ワーカーの使用済みスクリプトの集合とする。

  15. map の各 url について:

    1. usedSet が url を含まない場合、map[url] を削除する。

  16. registration の待機中のワーカーが null でない場合、次を行う:

    1. registration の待機中のワーカーを終了する。

    2. registration の待機中のワーカーと "redundant" を引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

  17. registration、"waiting"、registration のインストール中のワーカーを引数として渡して、登録状態を更新アルゴリズムを実行する。

  18. registration、"installing"、null を引数として渡して、登録状態を更新アルゴリズムを実行する。

  19. registration の待機中のワーカーと "installed" を 引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

  20. job を指定してジョブを完了を 呼び出す。

  21. このアルゴリズム内で呼び出されたワーカー状態を更新によってキューに入れられたすべてのタスクが実行されるまで待機する。

  22. registration を指定してアクティブ化を 試行を呼び出す。

    注:ここでアクティブ化を試行がアクティブ化をトリガーしない場合、既存のアクティブワーカーによって制御される最後のクライアントがアンロードされるとき、skipWaiting() が非同期に呼び出されたとき、または既存のアクティブワーカーのライフタイムを延長するプロミスが 決着したときに、アクティブ化が再度試行される。

アクティベート

入力

registration:ServiceWorker登録

出力

なし

  1. registration の待機中のワーカーが null の場合、これらの手順を中止する。

  2. registration のアクティブワーカーが null でない場合、次を行う:

    1. registration の終了する アクティブワーカー。

    2. registration のアクティブワーカーと "redundant" を引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

  3. registration、"active"、および registration の待機中のワーカーを引数として渡して、登録状態を更新アルゴリズムを実行する。

  4. registration、"waiting"、および null を引数として渡して、登録状態を更新アルゴリズムを実行する。

  5. registration のアクティブワーカーと "activating" を 引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

    注:アクティブワーカーが アクティブ化中になると、実行時のスクリプトエラーも、アクティブワーカーの強制終了も、 アクティブワーカーがアクティブ化されることを妨げない。

    注:アクティブ化 ハンドラーは、必須ではない作業(クリーンアップなど)を行うように設計すること。これは、特にアクティブ化中にブラウザーが終了した場合、 アクティブ化ハンドラーのすべてが完了まで実行されるとは限らないためである。 Service Worker は、アクティブ化ハンドラーが すべて正常に完了しなかった場合でも、適切に機能するように設計すべきである。

  6. matchedClients を、その作成 URLが registration のストレージキーおよび registration のスコープ URLに一致するサービスワーカークライアントのリストとする。

  7. matchedClients の各 client について、 client の担当イベントループ上で、DOM 操作タスクソースを使用して、次の 副手順を実行するタスクをキューに入れる:

    1. readyPromise を client のグローバルオブジェクトの ServiceWorkerContainer オブジェクトのready プロミスとする。

    2. readyPromise が null の場合、続行する。

    3. readyPromise が保留中の場合、 readyPromise の関連する設定オブジェクトにおいて registration を表すサービスワーカー 登録オブジェクトを取得した結果で readyPromise を解決する。

  8. registration を使用している 各サービスワーカークライアント client について:

    1. client のアクティブワーカーを registration の アクティブワーカーに設定する。

    2. client を引数としてコントローラー変更を通知アルゴリズムを 呼び出す。

  9. activeWorker を registration のアクティブワーカーとする。

  10. activeWorker と "activate" を指定してイベントをスキップすべきかアルゴリズムを実行した結果が false の場合、次を行う:

    1. activeWorker を指定してサービスワーカーを実行アルゴリズムを実行した結果が 失敗でない場合、次を行う:

      1. activeWorker のイベントループ上で、DOM 操作タスク ソースを使用して、次の手順を実行するタスク task をキューに入れる:

        1. e を、ExtendableEvent を用いてイベントを作成した結果とする。

        2. e の type 属性を activate に初期化する。

        3. activeWorker のグローバル オブジェクトに e を配送する。

        4. 非同期拡張を待機: e がアクティブでなくなるまで、並列に待機する。

      2. task が実行されるか、破棄されるまで待機する。

      3. 非同期拡張を待機とラベル付けされた手順が完了するまで待機する。

  11. registration のアクティブワーカーと "activated" を 引数として渡して、ワーカー状態を更新アルゴリズムを実行する。

アクティベート試行

入力

registration:ServiceWorker登録

出力

なし

  1. registration の waiting worker が null なら return。

  2. registration の active worker が null でなく、かつ registration の active worker の state が "activating" なら return。

    注: 既存active workerがまだactivating状態なら、waiting workerのアクティベートは遅延される。

  3. 以下のいずれかが真なら Activate(registration)を呼び出す:

ServiceWorkerGlobalScopeのセットアップ

入力

serviceWorker:ServiceWorker

出力

ServiceWorkerGlobalScope オブジェクトまたはnull

注: このアルゴリズムはCSPチェック等で使えるServiceWorkerGlobalScope またはnullを返す。serviceWorkerがactiveなServiceWorkerGlobalScopeを持つ場合はそれを返し、そうでなければ新規生成。

このアルゴリズムは、CSPやCOEPのようなセキュリティチェックに使えるService Workerを作成するために必要最小限のセットアップのみを行います。この仕様は、こうしたチェックが実行される前に、このアルゴリズムが呼ばれることを保証します。

仕様において、そのようなセキュリティチェックには、ServiceWorkerGlobalScope、 関連設定オブジェクト、 realm、 agent の作成が必要です。実装では、必要な作業量はこれより少ない可能性があります。したがって、実装はこのアルゴリズムに相当する処理でより少ない作業を行い、必要ならRun Service Workerでより多くの作業を実施しても構いません。ただし、その結果が観察可能な範囲で等価であること(特に、すべてのセキュリティチェックが同じ結果となること)が前提です。

  1. unsafeCreationTime を unsafe shared current time とする。

  2. もし serviceWorker が 実行中 であれば、serviceWorker の global object を返す。

  3. もし serviceWorker の state が "redundant" であれば、null を返す。

  4. もし serviceWorker の global object が null でなければ、serviceWorker の global object を返す。

  5. アサート: serviceWorker の start status は null である。

  6. setupFailed を false にする。

  7. globalObject を null にする。

  8. agent を Service Worker エージェントを取得した結果とし、そのコンテキストで次を実行する:

    1. realmExecutionContext を 新しいrealmの生成(agentおよび次のカスタマイズ指定)で得る:

      • グローバルオブジェクトとして、新しい ServiceWorkerGlobalScope オブジェクトを作成し、workerGlobalScopeとする。

    2. settingsObject を、次のアルゴリズムで定義される 環境設定オブジェクト の新しいインスタンスとする:

      レルム実行コンテキスト

      realmExecutionContextを返す。

      モジュールマップ

      workerGlobalScopeのモジュールマップを返す。

      API基底URL

      serviceWorkerのスクリプトURLを返す。

      オリジン

      それを登録したサービスワーカークライアントのオリジンを返す。

      サイト間の 祖先を持つか

      それを登録したサービスワーカークライアントのサイト間の 祖先を持つかを返す。

      ポリシーコンテナー

      workerGlobalScopeのポリシー コンテナーを返す。

      時刻起点

      workerGlobalScopeのオリジン間 分離機能を与えてunsafeCreationTimeを粗粒度化した結果を返す。

    3. settingsObjectのIDを新しい一意な不透明文字列に、作成URLを serviceWorkerのスクリプトURLに、トップレベル作成 URLをnullに、トップレベルオリジンを実装定義の値に、対象閲覧 コンテキストをnullに、またアクティブなサービス ワーカーをnullに設定する。

    4. workerGlobalScope の url に serviceWorker の script url を設定する。

    5. workerGlobalScope の policy container に serviceWorker の script resource の policy container を設定する。

    6. workerGlobalScope の type に serviceWorker の type を設定する。

    7. 新しい WorkerLocation オブジェクトを作成し、workerGlobalScope に関連付ける。

    8. もし グローバルオブジェクトのCSP初期化 アルゴリズムを workerGlobalScope で実行した結果が "Blocked" であれば、setupFailed を true にし、これらの手順を中止する。

    9. globalObject に workerGlobalScope を設定する。

  9. globalObject が null でなくなるか、setupFailed が true になるまで待つ。

  10. もし setupFailed が true であれば、null を返す。

  11. globalObject を返す。

ServiceWorkerの実行

入力

serviceWorker:ServiceWorker

forceBypassCache:オプションのboolean。デフォルトはfalse

出力

Completionまたは失敗

注: このアルゴリズムはServiceWorkerがrunning状態になるか起動失敗するまでブロックする。

  1. serviceWorkerが実行中である場合、serviceWorkerの 開始状態を返す。

  2. serviceWorkerの状態が「redundant」である場合、 失敗を返す。

  3. 表明:serviceWorkerの開始 状態はnullである。

  4. scriptを、serviceWorkerのスクリプトリソースとする。

  5. 表明:scriptはnullでない。

  6. startFailedをfalseとする。

  7. workerGlobalScopeを、serviceWorkerのグローバルオブジェクトとする。

  8. workerGlobalScopeがnullである場合:

    1. workerGlobalScopeを、serviceWorkerを用いてServiceWorkerGlobalScopeを設定する アルゴリズムを実行した結果に設定する。

    2. workerGlobalScopeがnullである場合、失敗を返す。

    3. serviceWorkerのグローバルオブジェクトを workerGlobalScopeに設定する。

  9. workerGlobalScopeのレルム実行コンテキストのエージェントを取得し、その コンテキスト内で次の手順を実行する:

    1. forceBypassCacheがtrueである場合、workerGlobalScopeのインポート スクリプト用キャッシュ強制迂回フラグを設定する。

    2. serviceWorkerがアクティブなワーカーであり、 serviceWorkerを包含するサービス ワーカー登録のタスクキュー内に キューに入れられたタスクがある場合、それらを元のタスクソースを使用して、同じ順序で serviceWorkerのイベントループのタスクキューにキューに入れる。

    3. evaluationStatusをnullとする。

    4. scriptがクラシックスクリプトである場合:

      1. evaluationStatusを、scriptをクラシックスクリプトとして実行した結果に 設定する。

      2. evaluationStatus.[[Value]]が空である場合、これはスクリプトが 評価されなかったことを意味する。startFailedをtrueに設定し、これらの手順を 中止する。

    5. そうでなく、scriptがモジュールスクリプトである場合:

      1. evaluationPromiseを、エラーの報告をfalseに設定して scriptをモジュールスクリプトとして実行した結果とする。

      2. 表明:evaluationPromise.[[PromiseState]]は 「pending」でない。

      3. evaluationPromise.[[PromiseState]]が「rejected」である場合:

        1. evaluationStatusをThrowCompletion(evaluationPromise.[[PromiseResult]])に 設定する。

      4. そうでない場合:

        1. evaluationStatusをNormalCompletion(undefined)に 設定する。

    6. スクリプトがサービスワーカーを終了するアルゴリズムによって 中止された場合、startFailedをtrueに設定し、これらの手順を中止する。

    7. serviceWorkerの開始状態を evaluationStatusに設定する。

    8. scriptの一度でも評価されたことがあるフラグが 設定されていない場合:

      1. settingsObjectのグローバルオブジェクトに 関連付けられたイベントリスナーのリストにある イベント型の各eventTypeについて:

        1. eventTypeを、workerGlobalScopeに関連付けられたサービス ワーカーの処理するイベント型の 集合に付加する。

        注記: この時点で グローバルオブジェクトに関連付けられたイベントリスナーのリストにイベントリスナーが 追加されていない場合、サービスワーカーの処理するイベント型の 集合は空集合のままとなる。

      2. scriptの一度でも評価されたことがある フラグを設定する。

      3. serviceWorkerのすべてのフェッチ リスナーが空であるフラグを設定解除する。

      4. ユーザーエージェントは、workerGlobalScopeを用いたすべてのフェッチリスナーが空であるか アルゴリズムがtrueを返す場合、serviceWorkerのすべての フェッチリスナーが空であるフラグを設定してもよい。

    9. settingsObjectによって指定された担当イベントループを、それが破棄されるまで 実行する。

    10. workerGlobalScopeのアクティブなタイマーのマップを消去する。

  10. serviceWorkerが実行中になるか、 startFailedがtrueになるまで待機する。

  11. startFailedがtrueである場合、失敗を返す。

  12. serviceWorkerの開始状態を返す。

fetchリスナーが全て空である

入力

workerGlobalScope:global object

出力

boolean

  1. workerGlobalScope の set of event types to handle が fetch を含まなければ true を返す。

  2. eventHandler を workerGlobalScope の event handler map["onfetch"]の値に設定。

  3. eventListenerCallbacks を legacy-obtain service worker fetch event listener callbacks(workerGlobalScope)の結果に設定。

  4. 各 eventListenerCallback について eventListenerCallbacks内で:

    1. callback を null とする。

    2. もし eventHandler が null でなく、eventListenerCallback が eventHandler の listener の callback と等しい場合、callback に ECMAScript値へ変換した eventHandler の value の結果を設定する。

    3. そうでなければ、callback に ECMAScript値へ変換した eventListenerCallback の結果を設定する。

    4. もし IsCallable(callback) が false なら、false を返す。

      注: Callback オブジェクトが handleEvent(event) を使っている場合、非空と見なされます。これは、handleEvent(event) のgetterを呼び出すことで、このチェック中にイベントリスナーが変更される可能性を避けるためです。

    5. もし callback の 関数本体 が空でない(すなわち 文 または 宣言 が存在する)なら、false を返す。

    注: () => {} のようなfetchリスナーを検出。一部サイトはPWA認定目的で空bodyのfetchリスナーを持つ。

  5. true を返す。

注: ユーザーエージェントは空fetchリスナーが不要で性能低下の可能性ある旨警告表示を推奨。

ServiceWorkerの終了

入力

serviceWorker:ServiceWorker

出力

なし

  1. serviceWorkerのメインループと並列に、次の手順を実行する:

    1. serviceWorkerGlobalScopeを、serviceWorkerのグローバルオブジェクトとする。

    2. serviceWorkerGlobalScopeのclosingフラグをtrueに設定する。

    3. serviceWorkerの延長されたイベントの集合から、すべての項目を削除する。

    4. serviceWorkerGlobalScopeのイベントループのタスクキュー内にキューに入れられた、タスクソースがフェッチ処理タスクソースまたは機能イベント処理 タスクソースのいずれかであるタスクがある場合、それらを元のタスクソースを使用して同じ順序で、 serviceWorkerを包含するサービス ワーカー登録の対応するタスクキューにキューに入れ、serviceWorkerGlobalScopeのイベントループのタスクキューから、すべてのタスク(タスクソースがフェッチ処理タスクソースでも機能イベント処理 タスクソースでもないタスクを含む)を処理せずに破棄する。

      注記: これは実質的に、 フェッチイベントおよびプッシュイベントなどのその他の機能イベントが登録のタスクキューに 退避される一方で、メッセージイベントを含むその他のタスクは破棄されることを意味する。

    5. serviceWorker内で現在実行中のスクリプトを中止する。

    6. serviceWorkerの開始状態をnullに設定する。

Fetch処理

Fetch処理アルゴリズムはfetch処理をServiceWorkerコンテキストへ委譲するエントリポイントです。

入力

request、リクエスト

fetchController、フェッチコントローラー

useHighResPerformanceTimers、ブール値

出力

レスポンスまたはサービス ワーカータイミング情報

  1. registrationをnullとする。

  2. clientを、requestのクライアントとする。

  3. reservedClientを、requestの予約済みクライアントとする。

  4. preloadResponseを新しいプロミスとする。

  5. workerRealmをnullとする。

  6. timingInfoを新しいサービスワーカータイミング情報とする。

  7. 表明:requestの宛先は 「serviceworker」でない。

  8. requestの宛先が「embed」 または「object」のいずれかである場合:

    1. nullを返す。

  9. そうでなく、requestが非サブリソースリクエストである場合:

    1. reservedClientがnullでなく、かつ環境設定オブジェクトである場合:

      1. reservedClientがセキュアコンテキストでない場合、nullを返す。

    2. そうでない場合:

      1. requestのURLが潜在的に信頼できる URLでない場合、nullを返す。

    3. requestがナビゲーションリクエストであり、それを引き起こしたナビゲーションがshift+reloadまたは同等の操作によって開始された場合、 nullを返す。

    4. reservedClientがnullでないことを表明する。

    5. storage keyを、reservedClientを与えてストレージキーを取得するを実行した結果とする。

    6. registrationを、storage keyおよびrequestのURLを与えてサービスワーカー登録を照合するを 実行した結果に設定する。

    7. registrationがnullであるか、registrationのアクティブなワーカーがnullである場合、nullを返す。

    8. requestの宛先が"report"でない場合、 reservedClientのアクティブなサービス ワーカーをregistrationのアクティブなワーカーに 設定する。

    注記: この時点から、サービスワーカークライアントは、そのアクティブなサービスワーカーを包含するサービスワーカー登録の使用を開始する。

  10. そうでなく、requestがサブリソースリクエストである場合:

    1. clientのアクティブなサービス ワーカーがnullでない場合、registrationを、clientのアクティブなサービス ワーカーを包含するサービス ワーカー登録に設定する。

    2. そうでない場合、nullを返す。

  11. activeWorkerを、registrationのアクティブなワーカーとする。

  12. shouldSoftUpdateを、次のいずれかがtrueである場合はtrue、それ以外の場合はfalseとする:

  13. activeWorkerのルータールールのリストが空でない場合:

    1. timingInfoのワーカー ルーター評価開始時刻を、useHighResPerformanceTimersを与えた粗粒度化された共有現在時刻に 設定する。

    2. sourceを、registrationのアクティブなワーカーおよび requestを用いてルーターソースを取得する アルゴリズムを実行した結果とする。

    3. sourceがnullでない場合:

      1. timingInfoのワーカー 一致ルーターソースをsourceに設定し、ワーカー 最終ルーターソースを"network"に 設定する。

      2. sourceが"network"である場合:

        1. shouldSoftUpdateがtrueである場合、 registrationを用いてソフト更新アルゴリズムを並列に実行する。

        2. timingInfoを返す。

      3. そうでなく、sourceが"cache"であるか、 source["cacheName"]が存在する場合:

        1. shouldSoftUpdateがtrueである場合、 registrationを用いてソフト更新アルゴリズムを並列に実行する。

        2. timingInfoのワーカー キャッシュ検索開始時刻を、useHighResPerformanceTimersを 与えた粗粒度化された共有 現在時刻に設定する。

        3. environmentをnullとする。

        4. requestが非サブリソース リクエストである場合:

          1. environmentをreservedClientに設定する。

        5. そうでない場合:

          1. environmentをclientに設定する。

        6. cachesを、environmentおよび 「caches」を用いてローカル ストレージボトルマップを取得するを実行した結果とする。

        7. cachesの各cacheName → cacheについて反復する。

          1. source["cacheName"]が存在し、かつ source["cacheName"]が cacheNameでない場合、継続する。

          2. requestResponsesを、request、新しいCacheQueryOptions、 およびcacheを用いてキャッシュを照会するを 実行した結果とする。

          3. requestResponsesが空のリストである場合、 timingInfoを返す。

          4. そうでない場合:

            1. requestResponseを、 requestResponsesの最初の要素とする。

            2. responseを、 requestResponseのレスポンスとする。

            3. globalObjectを、 activeWorkerのグローバル オブジェクトとする。

            4. globalObjectがnullである場合:

              1. globalObjectを、 activeWorkerを用いてServiceWorkerGlobalScopeを 設定するを実行した結果に設定する。

            5. globalObjectがnullである場合、 timingInfoを返す。

              注記: これはCORSチェックに 必要であるためにのみServiceWorkerGlobalScopeを作成する。 実装がここで実際にServiceWorkerGlobalScopeを作成することは 想定されていない。

            6. responseの種別が 「opaque」であり、 globalObjectのオリジン、 globalObject、""、および responseの内部 レスポンスを用いたオリジン間 リソースポリシーチェックがblockedを返す場合、 timingInfoを返す。

            7. timingInfoのワーカー 最終ルーターソースを"cache"に 設定する。

            8. resultのサービス ワーカータイミング情報を timingInfoに設定する。

            9. responseを返す。

        8. timingInfoを返す。

      4. そうでなく、sourceが"race-network-and-fetch-handler"であり、 requestのメソッドが`GET` である場合:

        1. shouldSoftUpdateがtrueである場合、 registrationを用いてソフト更新アルゴリズムを並列に実行する。

        2. queueを、競合 結果の空のキューとする。

        3. raceFetchControllerをnullとする。

        4. raceResponseを、その値が 「pending」である競合レスポンスとする。

        5. 次の下位手順を並列に実行する:

          1. fetchControllerの状態が 「terminated」または 「aborted」である場合、 raceResponseを、その値がnullである競合レスポンスに設定し、 これらの手順を中止する。

          2. raceFetchControllerを、requestを与えてフェッチを呼び出した結果に 設定する。その際、processResponseを、 レスポンス raceNetworkRequestResponseを与えた次の手順に設定する:

            1. 次の手順を実行するが、fetchControllerの状態が 「terminated」または 「aborted」になったとき中止する。

              1. raceResponseの値を raceNetworkRequestResponseに 設定する。

              2. raceNetworkRequestResponseのステータスが 成功ステータスで ある場合:

                1. raceNetworkResultを、そのルーティングされた レスポンスが raceNetworkRequestResponseで、 使用された ルートが"network"で ある競合 結果とする。

                2. raceNetworkResultを queueにエンキューする。

            2. 中止された場合で、 raceFetchControllerがnullでない場合:

              1. raceFetchControllerを中止する。

              2. raceResponseを、その値が nullである競合 レスポンスに設定する。

        6. preloadResponseをundefinedで解決する。

        7. 次の下位手順を並列に実行する:

          1. fetchHandlerResponseを、request、 registration、 useHighResPerformanceTimers、 timingInfo、workerRealm、 reservedClient、preloadResponse、 およびraceResponseを用いてフェッチ イベントを作成して配送するを実行した結果とする。

          2. fetchHandlerResponseがnullでもネットワークエラーでも なく、かつraceFetchControllerがnullでない場合、 raceFetchControllerを中止する。

          3. raceFetchHandlerResultを、そのルーティングされた レスポンスがfetchHandlerResponseであり、使用されたルートが "fetch-event"で ある競合結果とする。

          4. raceFetchHandlerResultをqueueにエンキューする。

        8. queueが空でなくなるまで待機する。

        9. resultを、queueをデキューした結果とする。

        10. routedResponseを、resultのルーティングされた レスポンスとする。

        11. routedResponseがnullである場合:

          1. timingInfoを返す。

        12. resultの使用されたルートが"network"で ある場合:

          1. routedResponseのサービスワーカー タイミング情報をtimingInfoに設定する。

        13. routedResponseのサービスワーカータイミング 情報のワーカー 最終ルーターソースを、resultの使用されたルートに設定する。

        14. routedResponseを返す。

      5. 表明:sourceは「fetch-event」である。

  14. responseForAutoPreloadをnullとする。

  15. requestがナビゲーションリクエストであり、requestのメソッドが`GET`であり、 registrationのアクティブなワーカーの処理するイベント型の集合が fetchを含み、かつregistrationのアクティブなワーカーのすべてのフェッチリスナーが 空であるフラグが設定されていない場合:

    1. registrationのナビゲーション プリロード有効フラグが設定されている場合:

      注記: 上記の条件のうち、 registrationのアクティブなワーカーの処理するイベント型の集合が fetchを含まないことを除いてすべてtrueである場合、開発者の意図が明確でないため、 ユーザーエージェントはコンソール警告を表示してもよい。

      1. preloadRequestを、リクエストrequestを複製した結果とする。

      2. preloadRequestHeadersを、preloadRequestのヘッダーリストとする。

      3. preloadResponseObjectを、ガードが 「immutable」である新しいHeaders オブジェクトに関連付けられた新しいResponse オブジェクトとする。

      4. preloadRequestHeadersに、名前が `Service-Worker-Navigation-Preload`で、値がregistrationのナビゲーション プリロードヘッダー値である新しいヘッダーを付加する。

      5. preloadRequestのサービスワーカーモードを 「none」に設定する。

      6. preloadFetchControllerをnullとする。

      7. 次の下位手順を並列に実行するが、 fetchControllerの状態が 「terminated」または「aborted」になったとき中止する:

        1. preloadFetchControllerを、 preloadRequestをフェッチした結果に設定する。

          navigationPreloadResponseのprocessResponseとして、 次の下位手順を実行する:

          1. navigationPreloadResponseの種別が 「error」である場合、 preloadResponseをTypeErrorで拒否し、 これらの下位手順を終了する。

          2. preloadResponseObjectを navigationPreloadResponseに関連付ける。

          3. preloadResponseを preloadResponseObjectで解決する。

      8. 中止された場合:

        1. deserializedErrorを、nullおよび workerRealmを与えて直列化された 中止理由を逆直列化するを実行した結果とする。

        2. preloadFetchControllerを deserializedErrorで中止する。

    2. そうでなく、timingInfoのワーカー 一致ルーターソースが「fetch-event」で ない場合、ユーザーエージェントは次の下位手順を実行してもよい:

      注記: ユーザーエージェントは、 起動コストを最小限に抑えるため、フェッチイベントの作成と並列にネットワークリクエストを 投機的に配送してもよい。

      1. 表明:timingInfoのワーカー 一致ルーターソースはnullである。

      2. autoPreloadFetchControllerをnullとする。

      3. responseForAutoPreloadを、その値が 「pending」である競合 レスポンスに設定する。

      4. 次の下位手順を並列に実行するが、 fetchControllerの状態が 「terminated」または「aborted」になったとき中止する:

        1. autoPreloadFetchControllerを、 requestを与えてフェッチを呼び出した結果に設定する。 その際、processResponseを、レスポンス autoPreloadRequestResponseを与えた次の手順に設定する:

          1. responseForAutoPreloadの値を autoPreloadRequestResponseに設定する。

      5. 中止された場合で、 autoPreloadFetchControllerがnullでない場合:

        1. autoPreloadFetchControllerを中止する。

        2. responseForAutoPreloadを、その値がnullである競合レスポンスに設定する。

      6. preloadResponseをundefinedで解決する。

  16. そうでない場合、preloadResponseをundefinedで解決する。

  17. fetchResultを、request、registration、 useHighResPerformanceTimers、timingInfo、workerRealm、 reservedClient、preloadResponse、および responseForAutoPreloadを用いてフェッチイベントを作成して配送するを 実行した結果とする。

  18. timingInfoのワーカー最終ルーター ソースが空文字列でない場合:

    1. timingInfoのワーカー最終 ルーターソースが"network"で あることを表明する。

    2. fetchResultがnullである場合、timingInfoを返す。

    3. そうでない場合:

      1. fetchResultのサービスワーカータイミング 情報のワーカー 最終ルーターソースが"network"で あることを表明する。

      2. fetchResultのサービスワーカータイミング 情報のワーカー 最終ルーターソースを"fetch-event"に 設定する。

  19. fetchResultを返す。

Fetchイベント生成・dispatch

入力

request、リクエスト

registration、サービスワーカー登録

useHighResPerformanceTimers、ブール値

timingInfo、サービスワーカータイミング情報

workerRealm、関連レルムであり、グローバルオブジェクトのもの

reservedClient、予約済みクライアント

preloadResponse、プロミス

raceResponse、競合レスポンスまたはnull

出力

レスポンスまたはnull

  1. responseをnullとする。

  2. eventCanceledをfalseとする。

  3. clientを、requestのクライアントとする。

  4. activeWorkerを、registrationのアクティブなワーカーとする。

  5. eventHandledをnullとする。

  6. handleFetchFailedをfalseとする。

  7. respondWithEnteredをfalseとする。

  8. networkErrorをネットワークエラーとする。

  9. raceResponseがnullでない場合:

    1. networkErrorのサービスワーカータイミング情報を timingInfoに設定する。

  10. shouldSoftUpdateを、次のいずれかがtrueである場合はtrue、それ以外の場合は falseとする:

  11. 「fetch」およびactiveWorkerを用いてイベントをスキップすべきかアルゴリズムを実行した結果が trueである場合:

    1. shouldSoftUpdateがtrueである場合、registrationを用いてソフト更新アルゴリズムを並列に実行する。

    2. nullを返す。

  12. activeWorkerのすべてのフェッチリスナーが 空であるフラグが設定されている場合:

    1. 並列に:

      1. activeWorkerの状態が「activating」である場合、 activeWorkerの状態が「activated」になるまで待機する。

      2. activeWorkerを用いてサービスワーカーを実行するアルゴリズムを 実行する。

      3. shouldSoftUpdateがtrueである場合、 registrationを用いてソフト更新アルゴリズムを 実行する。

    2. nullを返す。

  13. useHighResPerformanceTimersがtrueである場合、 useHighResPerformanceTimersをactiveWorkerのグローバルオブジェクトのオリジン間 分離機能に設定する。

  14. timingInfoの開始時刻を、 useHighResPerformanceTimersを与えた粗粒度化された共有現在時刻とする。

  15. activeWorkerの状態が「activating」である場合、 activeWorkerの状態が「activated」になるまで待機する。

  16. activeWorkerを用いてサービスワーカーを実行するアルゴリズムを実行した結果が 失敗である場合、handleFetchFailedをtrueに設定する。

  17. そうでない場合:

    1. workerRealmを、activeWorkerのグローバルオブジェクトの関連レルムに設定する。

    2. eventHandledを、workerRealm内の新しいプロミスに設定する。

    3. raceResponseがnullでない場合、activeWorkerのグローバルオブジェクトの競合レスポンス マップ[request]をraceResponseに設定する。

    4. 次の下位手順を実行するタスクtaskをキューに入れる:

      1. eを、FetchEventを用いてイベントを作成した結果とする。

      2. abortControllerを、workerRealmを用いた新しい AbortController オブジェクトとする。

      3. requestObjectを、request、ガードが 「immutable」である新しいHeaders オブジェクト、abortControllerのシグナル、および workerRealmを与えてRequest オブジェクトを作成した結果とする。

      4. eのtype 属性をfetchに 初期化する。

      5. eのcancelable 属性をtrueに初期化する。

      6. eのrequest 属性をrequestObjectに初期化する。

      7. eのpreloadResponseを preloadResponseに初期化する。

      8. clientがnullでない場合、eのclientId 属性をclientのIDに初期化する。

      9. requestが非サブリソースリクエストであり、 requestの宛先が"report"でなく、 かつreservedClientがnullでない場合、eのresultingClientId 属性をreservedClientのIDに初期化する。

      10. requestがナビゲーションリクエストである場合、 eのreplacesClientId 属性をrequestの置換対象クライアントIDに 初期化する。

      11. eのhandledを eventHandledに初期化する。

      12. timingInfoのフェッチ イベント配送時刻を、useHighResPerformanceTimersを与えた粗粒度化された共有現在 時刻とする。

      13. activeWorkerのグローバルオブジェクトに eを配送する。

      14. activeWorkerおよびeを用いてサービスワーカーの 延長イベント集合を更新するを呼び出す。

      15. eのrespond-with入力済み フラグが設定されている場合、respondWithEnteredをtrueに設定する。

      16. eの応答待機フラグが 設定されている場合:

        1. eの応答待機 フラグが設定解除されるまで待機する。

        2. eのrespond-with エラーフラグが設定されている場合、 handleFetchFailedをtrueに設定する。

        3. そうでない場合、responseをeの潜在的な レスポンスに設定する。

      17. responseがnullであり、requestの本体がnullでなく、かつ requestの本体のソースがnullである場合:

        1. requestの本体が使用不能である場合、 handleFetchFailedをtrueに設定する。

        2. そうでない場合、requestの本体をundefinedでキャンセルする。

      18. responseがnullでない場合、responseのサービスワーカータイミング 情報をtimingInfoに設定する。

      19. eのキャンセル済みフラグが設定されている場合、 eventCanceledをtrueに設定する。

      20. fetchControllerの状態が 「terminated」または「aborted」である場合:

        1. deserializedErrorを、 fetchControllerの直列化された 中止理由およびworkerRealmを与えて直列化された 中止理由を逆直列化するを実行した結果とする。

        2. abortController上で deserializedErrorを用いて中止を通知するタスクをキューに入れる。

      taskが破棄された場合、handleFetchFailedをtrueに設定する。

      taskは、activeWorkerのイベントループおよびフェッチ処理タスクソースを使用しなければ ならない。

  18. taskが実行されるか、handleFetchFailedがtrueになるまで待機する。

  19. shouldSoftUpdateがtrueである場合、registrationを用いてソフト更新アルゴリズムを並列に実行する。

  20. activeWorkerのグローバルオブジェクトの競合レスポンス マップ[request]が存在する場合、activeWorkerのグローバルオブジェクトの競合レスポンス マップ[request]を削除する。

  21. respondWithEnteredがfalseである場合:

    1. eventCanceledがtrueである場合:

      1. eventHandledがnullでない場合、 workerRealm内でeventHandledを「NetworkError」 DOMExceptionで拒否する。

      2. networkErrorを返す。

    2. eventHandledがnullでない場合、eventHandledを解決する。

    3. raceResponseがnullでなく、かつraceResponseの値がnullでない場合:

      1. raceResponseの値が 「pending」でなくなるまで待機する。

      2. raceResponseの値がレスポンスである場合、 raceResponseの値を返す。

    4. nullを返す。

  22. handleFetchFailedがtrueである場合:

    1. eventHandledがnullでない場合、workerRealm内で eventHandledを「NetworkError」 DOMExceptionで拒否する。

    2. networkErrorを返す。

  23. eventHandledがnullでない場合、eventHandledを解決する。

  24. responseを返す。

URLパターンの解析

入力

rawPattern、URLPatternCompatible

serviceWorker、サービスワーカー

出力

URLパターン

  1. baseURLをserviceWorkerのスクリプトURLとする。

  2. rawPatternおよびbaseURLを与えて、Web IDL値からURLパターンを構築する結果を返す。

ルーター条件の検証

入力

condition、RouterCondition

serviceWorker、サービスワーカー

出力

真偽値

  1. hasConditionをfalseにする。

  2. condition["urlPattern"] が存在する場合:

    1. rawPatternをcondition["urlPattern"]とする。

    2. rawPatternとserviceWorkerを渡してURLパターンの解析アルゴリズムを実行した結果をpatternとする。これが例外を投げた場合はcatchし、falseを返す。

    3. patternが正規表現グループを持つ場合、falseを返す。

      注:ユーザー定義正規表現の実行はセキュリティ上の懸念があるため、禁止されている。

    4. hasConditionをtrueにする。

  3. condition["requestMethod"] が存在する場合:

    1. methodをcondition["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. orConditionsをcondition["_or"]とする。

    3. orConditionsの各orConditionについて:

      1. orConditionとserviceWorkerを使ってルーター条件の検証アルゴリズムを実行し、falseならfalseを返す。

    4. hasConditionをtrueにする。

  8. condition["not"] が存在する場合:

    1. hasConditionがtrueなら、falseを返す。

      注:ルーター規則の理解を容易にするため、"not"条件は他の条件と相互排他である。

    2. condition["not"]とserviceWorkerを使ってルーター条件の検証アルゴリズムを実行し、falseならfalseを返す。

    3. hasConditionをtrueにする。

  9. hasConditionを返す。

ルーター条件のマッチング

入力

condition、RouterCondition

serviceWorker、サービスワーカー

request、リクエスト

出力

真偽値

注:複数の条件(例:urlPattern、runningStatus、requestMethodが設定されている場合)は、すべての条件が一致した場合にtrueが返される。

  1. condition["or"] が存在する場合:

    1. orConditionsをcondition["or"]とする。

    2. orConditionsの各orConditionについて:

      1. orCondition、serviceWorker、requestを使ってルーター条件のマッチングアルゴリズムを実行し、trueが返った場合はtrueを返す。

    3. falseを返す。

  2. condition["not"] が存在する場合:

    1. condition["not"]、serviceWorker、requestを使ってルーター条件のマッチングアルゴリズムを実行し、trueが返った場合はfalseを返す。

    2. trueを返す。

  3. それ以外:

    注:ルーター条件の検証アルゴリズムは、or、notと他の条件が排他されていることを保証する。

    1. condition["urlPattern"] が存在する場合:

      1. rawPatternをcondition["urlPattern"]とする。

      2. rawPatternとserviceWorkerを渡してURLパターンの解析アルゴリズムを実行した結果をpatternとする。

      3. patternとrequestのURLでマッチングを実行し、結果がnullならfalseを返す。

    2. condition["requestMethod"] が存在する場合:

      1. methodをcondition["requestMethod"]とする。

      2. methodを正規化する。

      3. requestのメソッドがmethodでなければ、falseを返す。

    3. condition["requestMode"] が存在する場合:

      1. modeをcondition["requestMode"]とする。

      2. requestのモードがmodeでなければ、falseを返す。

    4. condition["requestDestination"] が存在する場合:

      1. destinationをcondition["requestDestination"]とする。

      2. requestの宛先がdestinationでなければ、falseを返す。

    5. condition["runningStatus"] が存在する場合:

      1. runningStatusをcondition["runningStatus"]とする。

      2. runningStatusが"running"であり、serviceWorkerが稼働中でなければ、falseを返す。

      3. runningStatusが"not-running"であり、serviceWorkerが稼働中ならば、falseを返す。

    6. trueを返す。

ルーター登録制限の確認

入力

routerRules、ルーター規則のリスト

出力

真偽値

注: ルーター条件は_orやnotを用いて複雑かつネスト可能です。過度な処理を防ぐため、このアルゴリズムでは2つの制限を設けます。第一に、すべてのネストされた条件を含む合計条件数は1024を超えてはなりません。第二に、ネストの深さは10レベルまでに制限され、指数的計算を回避します。

  1. resultをルーター条件カウント結果とする。

  2. resultの条件数を1024に設定する。

  3. resultのクォータ超過をfalseに設定する。

  4. 各ruleをrouterRulesから取り出して:

    1. resultを、Count Router Inner Conditionsアルゴリズムの rule["condition"], result、10を渡した結果で更新する。

    2. resultのクォータ超過がtrueなら、falseを返す。

  5. trueを返す。

ルーター内条件数のカウント

入力

condition、RouterCondition

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を、ルーター内条件数のカウントをorCondition、result、depthで実行した結果で更新する。

      2. resultのクォータ超過がtrueなら、resultを返す。

  4. それ以外でcondition["not"] が存在する場合:

    1. depthを1減らす。

    2. resultを、ルーター内条件数のカウントを condition["not"]、result、depthで実行した結果で更新する。

    3. resultのクォータ超過がtrueなら、resultを返す。

  5. resultを返す。

ルーターソースの取得

入力

serviceWorker、サービスワーカー

request、リクエスト

出力

RouterSource またはnull

  1. 各ruleをserviceWorkerのルーター規則のリストから取り出して:

    1. rule["condition"]、serviceWorker、requestを使ってルーター条件のマッチングアルゴリズムを実行し、trueなら rule["source"]を返す。

  2. nullを返す。

イベントをスキップすべきか

入力

eventName、文字列

serviceWorker、サービスワーカー

出力

真偽値

注: 不要な遅延を避けるため、この仕様ではサービスワーカーのグローバルにイベントリスナーが初回スクリプト実行時に決定的に追加されていない場合、イベントのdispatchをスキップすることを許可します。

  1. serviceWorkerの処理するイベント型の集合がeventNameを含まない場合、ユーザーエージェントはスキップ可能としてtrueを返すことができる。

  2. falseを返す。

ファンクショナルイベントを発火

入力

eventName、文字列

eventConstructor、ExtendableEvent を拡張するイベントコンストラクター

registration、サービスワーカー登録

initialization、eventConstructor から構築される event の 省略可能なプロパティ初期化

postDispatchSteps、アクティブワーカーのイベント ループ上で実行する省略可能な手順。dispatchedEvent は、 ディスパッチされた eventConstructor のインスタンスに 設定される。

出力

なし

  1. 表明: registration のアクティブワーカーは null ではない。

  2. activeWorker を registration のアクティブワーカーとする。

  3. eventName および activeWorker を用いてイベントをスキップすべきかを実行した結果が true の場合、次を行う:

    1. registration が古い場合、並行して registration を用いてソフト更新アルゴリズムを 実行する。

    2. Return する。

  4. activeWorker の状態が "activating" の場合、 activeWorker の状態が "activated" になるまで待つ。

  5. activeWorker を用いてサービスワーカーを実行アルゴリズムを実行した結果が 失敗の場合、次を行う:

    1. registration が古い場合、並行して registration を用いてソフト更新アルゴリズムを 実行する。

    2. Return する。

  6. 次のサブステップを実行する task をタスクとしてキューに入れる:

    1. eventConstructor および activeWorker のグローバルオブジェクトの関連レルムを用いてイベントを作成した結果を event とする。

    2. initialization が null でない場合、event を initialization で初期化する。

    3. activeWorker のグローバルオブジェクト上で event をディスパッチする。

    4. activeWorker および event を用いてサービスワーカーの 拡張イベント集合を更新を呼び出す。

    5. postDispatchSteps が null でない場合、event を dispatchedEvent として渡して postDispatchSteps を実行する。

    task は、activeWorker のイベントループおよび機能イベント処理タスク ソースを使用しなければならない。

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

  8. registration が古い場合、並行して registration を用いてソフト更新アルゴリズムを 実行する。

特定の serviceWorkerRegistration 上で "amazingthing" イベント(型は AmazingThingEvent)を発火し、イベントオブジェクトのプロパティを初期化する例の説明は次のようになる:
  1. Fire Functional Event "amazingthing" を AmazingThingEvent を使って serviceWorkerRegistration 上で実行し、次のプロパティで初期化する:

    propertyName

    value

    anotherPropertyName

    anotherValue

    その後、dispatchedEvent を使って次のステップを実行する:

    1. サービスワーカーのイベントループ上で dispatchedEvent を使って必要な処理を行う。

初期化ステップとポストディスパッチステップは省略可能である。必要ない場合の記述は次のようになる:

  1. Fire Functional Event "whatever" を ExtendableEvent を使って serviceWorkerRegistration 上で実行する。

サービスワークラクライアントのアンロード処理

ユーザーエージェントは、サービスワーカー クライアントが文書のアンロード時クリーンアップ手順または終了によってアンロードされる際の一部として、これらの手順を実行し なければならない。

入力

client、サービスワーカークライアント

出力

なし

  1. 次の手順を不可分に実行する。

  2. registrationを、clientが使用しているサービスワーカー登録とする。

  3. registrationがnullである場合、これらの手順を中止する。

  4. 他のいずれかのサービスワーカークライアントが registrationを使用している場合、これらの手順を中止する。

  5. registrationが登録解除済みである場合、 registrationを用いて登録の消去を試行するを呼び出す。

  6. registrationを用いてアクティブ化を試行するを呼び出す。

ユーザーエージェントのシャットダウン処理

入力

なし

出力

なし

  1. 各 registration を registration map の values から反復する:

    1. もし registration の installing worker が null でなければ:

      1. もし registration の waiting worker が null で、かつ registration の active worker が null なら、Clear Registration を registration で呼び出し、ループの次の反復に進む。

      2. それ以外なら、registration の installing worker を null に設定する。

    2. もし registration の waiting worker が null でなければ、並列で 次を行う:

      1. Activate を registration で呼び出す。

サービスワーカー拡張イベント集合の更新

入力

worker、サービスワーカー

event、ExtendableEvent

出力

なし

  1. 断言: event の dispatch flag はセットされていない。

  2. 各 item について、worker の set of extended events を走査する:

    1. もし item が active でなければ、remove して worker の set of extended events から取り除く。

  3. もし event が active なら、append して worker の set of extended events に追加する。

登録解除 (Unregister)

入力

job(job)

出力

なし

  1. registration を、jobの ストレージキー と jobの スコープURL を指定して Get Registrationを実行した結果とする。

  2. registration が null なら:

    1. Resolve Job Promise を job と false で呼び出す。

    2. Finish Job を job とともに呼び出し、これらのステップを中止する。

  3. Remove registration map[(registrationのストレージキー, jobの スコープURL)] を削除する。

  4. Resolve Job Promise を job と true で呼び出す。

  5. Try Clear Registration を registration で呼び出す。

    Note: ここでTry Clear RegistrationがClear Registrationをトリガーしない場合は、 registrationを使用している最後のクライアントがアンロードされるか、 または登録されたサービスワーカーのextend lifetime promisesが解決されたときに、 Clear Registrationが再度試行される。

  6. Finish Job を job で呼び出す。

登録を設定

入力

storage key、ストレージ キー

scope、URL

updateViaCache、キャッシュ経由更新モード

出力

registration、サービスワーカー登録

  1. 次の手順を不可分に実行する。

  2. scopeString を、フラグメント除外フラグを設定して scope をシリアル化したものとする。

  3. registration を、新しいサービスワーカー登録とし、そのストレージキーを storage key に、スコープ URLを scope に、そしてキャッシュ経由更新モードを updateViaCache に設定する。

  4. 設定する: 登録マップ[(storage key, scopeString)] を registration にする。

  5. registration を返す。

登録をクリア

入力

registration、service worker registration

出力

なし

  1. 次のステップを原子的に実行する。

  2. もし registration の installing worker が null でなければ、次を行う:

    1. Terminate を registration の installing worker に対して実行する。

    2. Update Worker State を呼び出し、registration の installing worker と "redundant" を引数として渡す。

    3. Update Registration State を呼び出し、registration、"installing"、および null を引数として渡す。

  3. もし registration の waiting worker が null でなければ、次を行う:

    1. Terminate を registration の waiting worker に対して実行する。

    2. Update Worker State を呼び出し、registration の waiting worker と "redundant" を引数として渡す。

    3. Update Registration State を呼び出し、registration、"waiting"、および null を引数として渡す。

  4. もし registration の active worker が null でなければ、次を行う:

    1. Terminate を registration の active worker に対して実行する。

    2. Update Worker State を呼び出し、registration の active worker と "redundant" を引数として渡す。

    3. Update Registration State を呼び出し、registration、"active"、および null を引数として渡す。

登録クリア試行

入力

registration、service worker registration

出力

なし

  1. もしどの service worker client も 使用しておらず、かつ次のすべての条件が真であれば、Clear Registration を registration で呼び出す:

登録状態を更新

入力

registration、service worker registration

target、文字列("installing"、"waiting"、"active" のいずれか)

source、service worker または null

出力

なし

  1. registrationObjects を、registration に関連付けられたすべての ServiceWorkerRegistration オブジェクトを含む配列とする。

  2. target が "installing" である場合:

    1. registration の インストール中の Workerを source に設定する。

    2. registrationObjects 内の各 registrationObject について:

      1. registration の インストール中の Workerが null である場合は registrationObject の installing 属性を null に設定し、それ以外の場合は registrationObject の 関連する設定オブジェクト内で registration の インストール中の Workerを表す service worker オブジェクトを取得した結果に設定する タスクをキューに追加する。

  3. それ以外で target が "waiting" の場合、次を行う:

    1. registration の待機中のワーカーを source に設定する。

    2. registrationObjects 内の各 registrationObject について:

      1. タスクをキューに入れる。そのタスクは、 registration の待機中のワーカーが null の場合は registrationObject の waiting 属性を null に設定し、それ以外の場合は、 registrationObject の関連する設定オブジェクト内で registration の待機中のワーカーを表すサービスワーカー オブジェクトを取得した結果に設定する。

  4. それ以外で target が "active" の場合、次を行う:

    1. registration のアクティブワーカーを source に設定する。

    2. registrationObjects 内の各 registrationObject について:

      1. タスクをキューに入れる。そのタスクは、 registration のアクティブワーカーが null の場合は registrationObject の active 属性を null に設定し、それ以外の場合は、 registrationObject の関連する設定オブジェクト内で registration のアクティブワーカーを表すサービスワーカー オブジェクトを取得した結果に設定する。

    タスクは、registrationObject の関連する設定オブジェクトの担当イベントループおよびDOM 操作タスクソースを使用しなければならない。

ワーカー状態を更新

入力

worker、service worker

state、サービスワーカーの state

出力

なし

  1. 表明:state は "parsed" ではない。

    注: "parsed" は 初期状態である。サービスワーカーがこの状態に更新されることはない。

  2. worker の状態を state に設定する。

  3. settingsObjects を、そのオリジンが worker のスクリプト URLのオリジンである、すべての環境設定オブジェクトとする。

  4. settingsObjects の各 settingsObject について、settingsObject の担当イベントループ上で、DOM 操作タスクソースにおいて、次の 手順を実行するタスクをキューに入れる:

    1. objectMap を settingsObject のサービス ワーカーオブジェクトマップとする。

    2. objectMap[worker] が存在しない場合、これらの手順を中止する。

    3. workerObj を objectMap[worker] とする。

    4. workerObj の state を state に設定する。

    5. workerObj で statechange という名前のイベントを発火する。

コントローラ変更の通知

入力

client、サービスワーカークライアント

出力

なし

  1. 表明:client は null ではない。

  2. client が環境設定オブジェクトである場合、client が関連付けられている ServiceWorkerContainer オブジェクトで controllerchange という名前のイベントを発火するためのタスクをキューに入れる。

タスクは、client の担当イベントループおよびDOM 操作タスクソースを使用しなければならない。

サービスワーカー登録を照合

入力

storage key、storage key

clientURL、URL

出力

service worker registration または null

  1. 次のステップを原子的に実行する。

  2. clientURLString を clientURL の serialize 結果とする。

  3. matchingScopeString を空文字列にする。

  4. scopeStringSet を空のリストにする。

  5. 各 (entry storage key, entry scope) を registration map の keys から反復する:

    1. もし storage key が entry storage key と 等しい なら、append して entry scope を scopeStringSet の末尾に追加する。

  6. matchingScopeString を、scopeStringSet の中で clientURLString が先頭に持つ最長の値に設定する(存在する場合)。

    注意: このステップの URL 文字列の照合はパス構造ベースではなくプレフィックスベースである。例えばクライアント URL 文字列 "https://example.com/prefix-of/resource.html" はスコープ "https://example.com/prefix" に一致する。HTTP(S) の URL は常に起点部分に末尾スラッシュが付いてシリアライズされるため、同一オリジンの安全性が保たれる。

  7. matchingScope を null にする。

  8. もし matchingScopeString が空文字列でないなら:

    1. matchingScope を matchingScopeString を parse した結果に設定する。

    2. 断言: matchingScope の origin と clientURL の origin は 同一オリジン である。

  9. Get Registration を storage key と matchingScope で実行した結果を返す。

登録を取得

入力

storage key、storage key

scope、URL

出力

service worker registration または null

  1. 次のステップを原子的に実行する。

  2. scopeString を空文字列にする。

  3. もし scope が null でなければ、scopeString を scope の serialize(exclude fragment flag を設定)した結果に設定する。

  4. 各 (entry storage key, entry scope) → registration を registration map から反復する:

    1. もし storage key が entry storage key と 等しく、かつ scopeString が entry scope と一致するなら、registration を返す。

  5. null を返す。

最新のワーカーを取得

入力

registration、service worker registration

出力

newestWorker、service worker または null

  1. 次のステップを原子的に実行する。

  2. newestWorker を null にする。

  3. もし registration の installing worker が null でなければ、registration の installing worker を newestWorker に設定する。

  4. そうでなくてもし registration の waiting worker が null でなければ、registration の waiting worker を newestWorker に設定する。

  5. さらにそうでなくてもし registration の active worker が null でなければ、registration の active worker を newestWorker に設定する。

  6. newestWorker を返す。

サービスワーカーに保留中イベントがないか

入力

worker、service worker

出力

真または偽、ブール値

  1. worker の set of extended events の各 event について:

    1. もし event が active なら、false を返す。

  2. true を返す。

クライアントを作成

入力

client、service worker client

出力

clientObject、Client オブジェクト

  1. clientObject を新しい Client オブジェクトとする。

  2. clientObject の service worker client を client に設定する。

  3. clientObject を返す。

ウィンドウクライアント 作成

入力

client、service worker client

frameType、文字列

visibilityState、文字列

focusState、ブール値

ancestorOriginsList、リスト

出力

windowClient、WindowClient オブジェクト

  1. windowClient を新しい WindowClient オブジェクトとする。

  2. windowClient の service worker client を client に設定する。

  3. windowClient の frame type を frameType に設定する。

  4. windowClient の visibility state を visibilityState に設定する。

  5. windowClient の focus state を focusState に設定する。

  6. windowClient の ancestor origins array を、ancestorOriginsList から作成した frozen array に設定する。

  7. windowClient を返す。

フレームタイプを取得

入力

navigable、navigable

出力

frameType、文字列

  1. もし navigable の parent が null でなければ、"nested" を返す。

  2. もし navigable の active browsing context が auxiliary browsing context なら、"auxiliary" を返す。

  3. "top-level" を返す。

Get Client Promise を解決

入力

client、service worker client

promise、promise

出力

なし

  1. client が環境設定オブジェクトである場合、次を行う:

    1. client がセキュアコンテキストでない場合、promise の関連する設定オブジェクトの担当イベントループ上で、DOM 操作タスクソースを使用して、 promise を "SecurityError" DOMException で拒否するタスクをキューに入れ、 これらの手順を中止する。

  2. それ以外の場合:

    1. client の作成 URLが潜在的に信頼できる URLでない場合、promise の関連する設定オブジェクトの担当イベントループ上で、DOM 操作タスクソースを使用して、 promise を "SecurityError" DOMException で拒否するタスクをキューに入れ、 これらの手順を中止する。

  3. client が環境設定オブジェクトであり、かつウィンドウ クライアントでない場合、次を行う:

    1. clientObject を、client を引数としてクライアントを作成アルゴリズムを 実行した結果とする。

    2. promise の関連する設定オブジェクトの担当イベントループ上で、DOM 操作タスクソースを使用して、 promise を clientObject で解決するタスクをキューに入れ、 これらの手順を中止する。

  4. それ以外の場合:

    1. browsingContext を null とする。

    2. client が環境設定オブジェクトである場合、 browsingContext を client のグローバルオブジェクトの閲覧コンテキストに設定する。

    3. それ以外の場合、browsingContext を client のターゲット閲覧 コンテキストに設定する。

    4. navigable を、browsingContext をアクティブ閲覧コンテキストとするナビゲーション可能とする。

    5. browsingContext のイベントループ上で、ユーザー操作タスクソースを使用して、 次の手順を実行するタスクをキューに入れる:

      1. frameType を、navigable を指定してフレームタイプを取得 を実行した結果とする。

      2. visibilityState を browsingContext のアクティブドキュメントの visibilityState 属性値とする。

      3. focusState を、browsingContext のアクティブドキュメントを引数としてフォーカスを持つ手順を実行した結果とする。

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

      5. client がウィンドウクライアントである場合、 ancestorOriginsList を browsingContext のアクティブドキュメントの祖先オリジン リストに関連付けられたリストに設定する。

      6. promise の関連する設定オブジェクトの 担当イベントループ上で、DOM 操作タスク ソースを使用して、次の手順を実行するタスクをキューに入れる:

        1. client の破棄済み フラグが設定されている場合、promise を undefined で解決し、 これらの手順を中止する。

        2. windowClient を、client、frameType、visibilityState、 focusState、および ancestorOriginsList を指定してウィンドウクライアントを作成を実行した結果とする。

        3. promise を windowClient で解決する。

キャッシュを照会

入力

requestQuery、request

options、CacheQueryOptions オブジェクト、任意

targetStorage、request response list、任意

出力

resultList、request response list

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

  2. storage を null にする。

  3. もし オプション引数 targetStorage が省略されていれば、storage を relevant request response list に設定する。

  4. そうでなければ、storage を targetStorage に設定する。

  5. 各 requestResponse を storage から反復する:

    1. cachedRequest を requestResponse の request にする。

    2. cachedResponse を requestResponse の response にする。

    3. もし Request Matches Cached Item を requestQuery、cachedRequest、cachedResponse、options で実行した結果が true なら:

      1. requestCopy を cachedRequest のコピーとする。

      2. responseCopy を cachedResponse のコピーとする。

      3. requestCopy/responseCopy を resultList に追加する。

  6. resultList を返す。

リクエストがキャッシュ項目に一致するか (Request Matches Cached Item)

入力

requestQuery、リクエスト

request、リクエスト

response、レスポンスまたはnull、省略可能、既定値はnull

options、CacheQueryOptions オブジェクト、省略可能

出力

ブール値

  1. もし options["ignoreMethod"] が false で、かつ request の method が `GET` でなければ、false を返す。

  2. queryURL を requestQuery の url とする。

  3. cachedURL を request の url とする。

  4. もし options["ignoreSearch"] が true なら:

    1. cachedURL の query を空文字列に設定する。

    2. queryURL の query を空文字列に設定する。

  5. もし queryURL が cachedURL と exclude fragment flag を設定して 等しく なければ、false を返す。

  6. もし response が null、または options["ignoreVary"] が true、または response の header list が `Vary` を含まないなら、true を返す。

  7. fieldValues を、リスト として、 Vary ヘッダーのフィールド値に対応する要素で構成する(名前が Vary のヘッダーの値について)。

  8. 各 fieldValue について:

    1. もし fieldValue が "*" とマッチするか、または fieldValue に対する request の header list と組み合わせた combined value が、同じ fieldValue に対する requestQuery のヘッダーと組み合わせた値に一致しない場合、false を返す。

  9. true を返す。

バッチキャッシュ操作

入力

operations、リスト。各要素は cache batch operation オブジェクト。

出力

resultList、request response list

  1. cache を relevant request response list とする。

  2. backupCache を cache のコピーである新しい request response list とする。

  3. addedItems を空の リスト とする。

  4. 次のサブステップを原子的に実行してみる:

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

    2. 各 operation を operations から反復する:

      1. もし operation の type が "delete" でも "put" でもなければ、throw で TypeError を投げる。

      2. もし operation の type が "delete" で、かつ operation の response が null でなければ、throw で TypeError を投げる。

      3. もし Query Cache を operation の request、operation の options、および addedItems で実行した結果が空でなければ、throw で "InvalidStateError" DOMException を投げる。

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

      5. もし operation の type が "delete" なら:

        1. requestResponses を Query Cache を operation の request と operation の options で実行した結果に設定する。

        2. 各 requestResponse を requestResponses から反復する:

          1. Remove して、cache から requestResponse に一致するアイテムを削除する。

      6. それ以外で、もし operation の type が "put" なら:

        1. もし operation の response が null なら、throw で TypeError を投げる。

        2. r を operation の request の関連付けられた request とする。

        3. もし r の url の scheme が "http" または "https" のいずれでもなければ、throw で TypeError を投げる。

        4. もし r の method が `GET` でなければ、throw で TypeError を投げる。

        5. もし operation の options が null でなければ、throw で TypeError を投げる。

        6. requestResponses を Query Cache を operation の request で実行した結果に設定する。

        7. 各 requestResponse を requestResponses から反復する:

          1. Remove して、cache から requestResponse に一致するアイテムを削除する。

        8. append して operation の request/operation の response を cache に追加する。

        9. もし 前の 2 ステップ のキャッシュ書き込みが許可されたクォータを超えて失敗した場合、throw で QuotaExceededError を投げる。

        10. append して operation の request/operation の response を addedItems に追加する。

      7. append して operation の request/operation の response を resultList に追加する。

    3. resultList を返す。

  5. もし例外が 投げられた 場合、次を行う:

    1. Remove して、items をすべて relevant request response list から取り除く。

    2. 各 requestResponse を backupCache から反復する:

      1. append して requestResponse を relevant request response list に戻す。

    3. throw してその例外を再度投げる。

    注意: 例外が 投げられた 場合、実装はバッチ操作ジョブ中に行われたキャッシュストレージへの変更を元に戻す(ロールバックする)。

非同期モジュールか

入力

record、Module Record

moduleMap、module map

base、URL

seen、set(URLs の)

出力

ブール値

  1. もし record が Cyclic Module Record でなければ、false を返す。

  2. もし record.[[Async]] が true なら、true を返す。

  3. 各 文字列 requested を record.[[RequestedModules]] から反復する:

    1. url を resolve a module specifier を base と requested で行った結果とする。

    2. 断言: url は失敗にならない。なぜならこの二つの引数でのモジュールスペシファイア解決は以前に成功しているはずだからである。

    3. もし seen が url を含まないなら:

      1. append して url を seen に追加する。

      2. もし moduleMap[url] がレコードを持たないなら、false を返す。

      3. もし Is Async Module を moduleMap[url] のレコード、moduleMap、base、および seen で実行した結果が true なら、true を返す。

  4. false を返す。

レースレスポンスを検索

入力

request、リクエスト

出力

レスポンス または null

  1. registrationをnullとする。

  2. requestが非サブリソースリクエストである場合:

    1. requestの予約済みクライアントがnullである場合、 nullを返す。

    2. storage keyを、requestの予約済みクライアントを与えてストレージキーを取得するを実行した結果とする。

    3. registrationを、storage keyおよびrequestのURLを与えてサービスワーカー登録を照合するを 実行した結果に設定する。

  3. そうでなく、requestがサブリソースリクエストである場合:

    1. clientを、requestのクライアントとする。

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

    3. registrationを、clientのアクティブなサービス ワーカーを包含するサービス ワーカー登録に設定する。

  4. それ以外の場合、nullを返す。

  5. activeWorkerを、registrationのアクティブなワーカーとする。

  6. mapを、activeWorkerのグローバルオブジェクトの競合レスポンスマップとする。

  7. map[request]が存在する 場合:

    1. entryをmap[request]とする。

    2. entryの値が「pending」でなくなるまで 待機する。

    3. entryの値がレスポンスである場合、 entryの値を複製した結果を返す。

  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]
スクリプティングポリシー. 編集者草案. URL: https://wicg.github.io/csp-next/scripting-policy.html
[CSP3]
Mike West; Antonio Sartori. コンテンツセキュリティポリシー レベル 3. 2026年8月13日. WD. URL: https://www.w3.org/TR/CSP3/
[DOM]
Anne van Kesteren. DOM 標準. リビングスタンダード. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript 言語仕様. URL: https://tc39.es/ecma262/multipage/
[FETCH]
Anne van Kesteren. Fetch 標準. リビング スタンダード. URL: https://fetch.spec.whatwg.org/
[FileAPI]
Marijn Kruisselbrink. File API. 2026年6月4日. WD. URL: https://www.w3.org/TR/FileAPI/
[HR-TIME-3]
Yoav Weiss. 高分解能時間. 2026年3月24日. WD. URL: https://www.w3.org/TR/hr-time-3/
[HTML]
Anne van Kesteren; et al. HTML 標準. リビングスタンダード. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra 標準. リビングスタンダード. URL: https://infra.spec.whatwg.org/
[MIMESNIFF]
Gordon P. Hemsley. MIME スニッフィング標準. リビングスタンダード. URL: https://mimesniff.spec.whatwg.org/
[NAVIGATION-TIMING-2]
Yoav Weiss; Noam Rosenthal. Navigation Timing レベル 2. 2026年2月25日. WD. URL: https://www.w3.org/TR/navigation-timing-2/
[PAGE-LIFECYCLE]
Page Lifecycle. コミュニティグループ草案 レポート. URL: https://wicg.github.io/page-lifecycle/
[RESOURCE-TIMING]
Yoav Weiss; Noam Rosenthal. Resource Timing. 2026年4月20日. CRD. URL: https://www.w3.org/TR/resource-timing/
[RFC2119]
S. Bradner. RFC において要件レベルを 示すために用いるキーワード. 1997年3月. 現行最良実践. URL: https://datatracker.ietf.org/doc/html/rfc2119
[RFC5234]
D. Crocker, Ed.; P. Overell. 構文仕様のための 拡張 BNF: ABNF. 2008年1月. インターネット標準. URL: https://www.rfc-editor.org/info/rfc5234/
[RFC7230]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): メッセージ構文とルーティング. 2014年6月. 標準化提案. URL: https://httpwg.org/specs/rfc7230.html
[RFC7231]
R. Fielding, Ed.; J. Reschke, Ed.. Hypertext Transfer Protocol (HTTP/1.1): セマンティクスと内容. 2014年6月. 標準化提案. URL: https://httpwg.org/specs/rfc7231.html
[SCREEN-CAPTURE]
Jan-Ivar Bruaroey; Elad Alon. 画面 キャプチャ. 2026年7月23日. WD. URL: https://www.w3.org/TR/screen-capture/
[SECURE-CONTEXTS]
Mike West. セキュアコンテキスト. 2023年11月10日. CRD. URL: https://www.w3.org/TR/secure-contexts/
[STORAGE]
Anne van Kesteren. Storage 標準. リビング スタンダード. URL: https://storage.spec.whatwg.org/
[STREAMS]
Adam Rice; et al. Streams 標準. リビング スタンダード. URL: https://streams.spec.whatwg.org/
[TRUSTED-TYPES]
Krzysztof Kotowicz. Trusted Types. 2026年6月23日. WD. URL: https://www.w3.org/TR/trusted-types/
[URL]
Anne van Kesteren. URL 標準. リビングスタンダード. URL: https://url.spec.whatwg.org/
[URLPATTERN]
Ben Kelly; Jeremy Roman; 宍戸俊哉 (Shunya Shishido). URL Pattern 標準. リビングスタンダード. URL: https://urlpattern.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL 標準. リビング スタンダード. 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<ServiceWorkerRegistration> 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のクラシックワーカースクリプト取得アルゴリズム及びモジュールワーカースクリプトグラフ取得アルゴリズムはjobのclientを引数に取ります。jobのclientはソフト更新アルゴリズムから渡される際に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?