FetchEvent.respondWith()
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 を変更することなくサイトが「代替の」ウェブページを提供できるということを意味します。
構文
respondWith(response)
引数
返値
なし (undefined
)。
例外
NetworkError
DOMException
-
上記の「グローバルルール」にヒントがあるように、ネットワークエラーは
FetchEvent.request.mode
とResponse.type
の値の組み合わせで起動されます。 InvalidStateError
DOMException
-
イベントが配信されていないか、
respondWith()
が既に呼び出されています。
例
この fetch イベントはキャッシュ API からのレスポンスを返そうとし、ない場合にはネットワークにフォールバックします。
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
が返ってくるまで呼び出すことです。
仕様書
Specification |
---|
Service Workers # fetch-event-respondwith |
ブラウザーの互換性
BCD tables only load in the browser