FetchEvent: respondWith() 方法

Baseline 廣泛可用 *

此功能已成熟,可跨多種裝置和瀏覽器版本工作。它自 ⁨2018 年 4 月⁩ 起已在所有瀏覽器中可用。

* 此特性的某些部分可能存在不同級別的支援。

注意:此功能僅在 Service Workers 中可用。

FetchEventrespondWith() 方法會阻止瀏覽器的預設 fetch 處理,並允許您自己提供一個 Response 的 Promise。

在大多數情況下,您可以提供接收方能夠理解的任何響應。例如,如果一個 <img> 發起了請求,響應體就需要是影像資料。出於安全原因,有一些全域性規則。

指定資源的最終 URL

從 Firefox 59 開始,當 service worker 為 FetchEvent.respondWith() 提供 Response 時,Response.url 值將被傳播到被攔截的網路請求中,作為最終解析的 URL。如果 Response.url 值是空字串,則使用 FetchEvent.request.url 作為最終 URL。

過去,在所有情況下,FetchEvent.request.url 都被用作最終 URL。提供的 Response.url 被有效忽略。

這意味著,例如,如果 service worker 攔截了一個樣式表或 worker 指令碼,那麼提供的 Response.url 將用於解析任何相對的 @importimportScripts() 子資源載入(Firefox bug 1222008)。

對於大多數型別的網路請求,此更改沒有影響,因為您無法觀察到最終 URL。但有一些情況,它確實很重要。

  • 如果攔截了 fetch(),那麼您可以在結果的 Response.url 上觀察到最終 URL。
  • 如果攔截了 worker 指令碼,那麼最終 URL 用於設定 self.location,並用作 worker 指令碼中相對 URL 的基礎 URL。
  • 如果攔截了樣式表,那麼最終 URL 將用作解析相對 @import 載入的基礎 URL。

請注意,Windowiframe 的導航請求不使用最終 URL。HTML 規範處理導航重定向的方式最終會將請求 URL 用於生成的 Window.location。這意味著網站仍然可以在離線時提供網頁的“備用”檢視,而不會更改使用者可見的 URL。

語法

js
respondWith(response)

引數

response

一個 Response 或一個解析為 ResponsePromise。否則,將向 Fetch 返回一個網路錯誤。

返回值

無(undefined)。

異常

NetworkError DOMException

FetchEvent.request.modeResponse.type 值出現某些組合時,會觸發網路錯誤,如上面“全域性規則”中所提示。返回此錯誤。

InvalidStateError DOMException

如果事件尚未分派或 respondWith() 已被呼叫,則返回此值。

示例

此 fetch 事件嘗試從快取 API 返回響應,否則回退到網路。

js
addEventListener("fetch", (event) => {
  // Prevent the default, and handle the request ourselves.
  event.respondWith(
    (async () => {
      // Try to get the response from a cache.
      const cachedResponse = await caches.match(event.request);
      // Return it if we found one.
      if (cachedResponse) return cachedResponse;
      // If we didn't find a match in the cache, use the network.
      return fetch(event.request);
    })(),
  );
});

注意: caches.match() 是一個方便的方法。等效的功能是按順序(由 caches.keys() 返回的順序)在每個快取上呼叫 cache.match(),直到返回 Response

規範

規範
Service Workers
# fetch-event-respondwith

瀏覽器相容性

另見