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

浏览器兼容性

另见