このページはコミュニティーの尽力で英語から翻訳されました。MDN Web Docs コミュニティーについてもっと知り、仲間になるにはこちらから。

View in English Always switch to English

FetchEvent.respondWith()

Baseline
広く利用可能
*

この機能は広く実装されており、多くのバージョンの端末やブラウザーで動作します。2018年4月以降、すべてのブラウザーで利用可能です。

* この機能の一部は、対応レベルが異なる場合があります。

respondWith() は FetchEvent インターフェイスのメソッドで、ブラウザー既定の fetch 処理を抑止して、自分自身で Response 用のプロミスを提供できるようにします。

たいていの場合、受信者が理解できるどんなレスポンスでも提供できます。例えば、<img> がリクエストを開始した場合、レスポンス本体には画像データが必要です。セキュリティの理由から、グローバルルールが少しあります。

  • type が "opaque" (不透明)の Response オブジェクトを返すことができるのは、 fetchEvent.request オブジェクトの mode が "no-cors" の場合だけです。これはプライベートなデータの漏洩を防ぎます。
  • type が "opaqueredirect" (不透明なリダイレクト)の Response オブジェクトを返すことができるのは、fetchEvent.request オブジェクトの mode が "manual" の場合だけです。
  • fetchEvent.request オブジェクトの mode が "same-origin" の場合、type が "cors" の Response オブジェクトを返すことはできません。

リソースの最終 URL を指定する

Firefox 59 以降、サービスワーカーが FetchEvent.respondWith() に Response を提供すると、Response.url 値は最終的に解決された URL として、ネットワークリクエストに介入する際に伝搬されるようになりました。Response.url 値が空文字列の場合は、FetchEvent.request.url が最終的な URL として使用されます。

かつては FetchEvent.request.url がすべての場合に最終 URL として使われていました。与えられた Response.url は実際には無視されていました。

つまり、例えば、サービスワーカーがスタイルシートやワーカースクリプトに介入すると、与えられた Response.url が、サブリソースが読み込む相対的な @import や importScripts() の代わりに使われます (Firefox バグ 1222008)。

たいていのネットワークリクエストに対して、最終 URL を観測できないためこの変更は影響ありません。しかし、少しだけ関係する場合があります。

  • fetch() が介入された場合、結果の Response.url で最終 URL を観測できます。
  • ワーカースクリプトが介入された場合、最終 URL は self.location をセットするのに使われ、ワーカースクリプトの相対 URL の代わりのベース URL として使われます。
  • スタイルシートが介入された場合、最終 URL は相対的な @import 読み込みの代わりのベース URL として使われます。

Window と iframe のナビゲーションリクエストはこの最終 URL を使わ「ない」ことに注意してください。HTML 仕様のナビゲーションのリダイレクトの処理方法では、Window.location のためにリクエスト URL を使います。これは、オフラインの時に、ユーザーに見える URL を変更することなくサイトが「代替の」ウェブページを提供できるということを意味します。

構文

js
respondWith(response)

引数

response

Response または Response に解決される Promise。それ以外の場合は、ネットワークエラーがフェッチ元に返されます。

返値

なし (undefined)。

例外

NetworkError DOMException

上記の「グローバルルール」にヒントがあるように、ネットワークエラーは FetchEvent.request.mode と Response.type の値の組み合わせで起動されます。

InvalidStateError DOMException

イベントが配信されていないか、respondWith() が既に呼び出されています。

例

この fetch イベントはキャッシュ API からのレスポンスを返そうとし、ない場合にはネットワークにフォールバックします。

js
addEventListener("fetch", (event) => {
  // 既定の動作を抑止し、リクエストを自分で処理します。
  event.respondWith(
    (async () => {
      // キャッシュからレスポンスを取得しようとします。
      const cachedResponse = await caches.match(event.request);
      // 見つかったらそれを返します。
      if (cachedResponse) return cachedResponse;
      // キャッシュ内に一致するものが見つからなかった場合は、ネットワークを使用します。
      return fetch(event.request);
    })(),
  );
});

メモ: caches.match() は便利なメソッドです。同等の機能は、cache.match() をそれぞれのキャッシュに対して(caches.keys() が返す順に)Response が返ってくるまで呼び出すことです。

仕様書

仕様書
Service Workers Nightly
# fetch-event-respondwith

ブラウザーの互換性

関連情報