Window: fetchLater() 方法
Window 接口的 fetchLater() 方法创建了一个延迟抓取。
fetchLater() 请求会在页面导航离开(页面被销毁或进入 bfcache),或者在提供的 activateAfter 超时后发送——以先发生者为准。
fetchLater() 方法返回一个 FetchLaterResult 对象,其中包含一个 activated 值,表示请求是否已发送。请注意,该方法不返回实际抓取的结果(因为它通常在文档被销毁后发送),并且抓取的整个响应,包括正文和标头,都会被忽略。
请求主体为 ReadableStream 的请求无法被延迟。
fetchLater() 方法由 connect-src 内容安全策略指令控制,而不是由检索到的资源的指令控制。
语法
fetchLater(resource)
fetchLater(resource, options)
参数
fetchLater() 方法接受与 fetch() 相同的所有参数,但增加了一个 activateAfter 选项。
resource-
这定义了您希望抓取的资源。与
fetch()相同,这可以是- 一个字符串或任何其他具有 stringifier 的对象——包括一个
URL对象——它提供您要抓取的资源的 URL。URL 可以相对于基本 URL,在窗口上下文中,基本 URL 是文档的baseURI。 - 一个
Request对象。
- 一个字符串或任何其他具有 stringifier 的对象——包括一个
options可选-
一个
DeferredRequestInit对象,其中包含您要应用于请求的任何自定义设置,包括一个activateAfter超时值,它定义了结果在发送前应延迟多长时间。
异常
fetch() 的相同异常可能会针对 fetchLater() 抛出,以及以下附加异常
QuotaExceededError-
由于超出可用配额,此功能的使用被阻止。有关更多详细信息,请参阅
fetchLater()配额。fetchLater()的调用者几乎在所有情况下都应保持防御性并捕获QuotaExceededError错误,尤其是当他们嵌入第三方 JavaScript 时。 RangeErrorDOMException-
当指定负
activateAfter值时抛出。 TypeErrorDOMException-
除了
fetch()的原因外,此异常还会针对ReadableStream请求(无法延迟)或使用不可信 URL(例如http://)时抛出。
返回值
一个 FetchLaterResult,其中包含一个 activated 布尔属性,指示请求是否已发送。
注意:一旦抓取请求发送,其响应——包括主体和标头——将不可用并被忽略。
示例
fetchLater() 配额文章提供了配额如何应用的示例。
将 GET 请求延迟到页面导航离开或关闭
fetchLater("/send_beacon");
将 POST 请求延迟约一分钟
在此示例中,我们创建一个 Request,并提供一个 activateAfter 值以将请求发送延迟 60,000 毫秒(或一分钟)
fetchLater("/send_beacon", {
method: "POST",
body: getBeaconData(),
activateAfter: 60000, // 1 minute
});
注意:实际发送时间未知,因为浏览器可能会等待更长或更短的时间,例如为了优化延迟抓取的批处理。
通过 try/catch 将 POST 请求延迟约一分钟
与上述示例相同,但最佳实践是将其封装在 try/catch 中
try {
fetchLater("/send_beacon", {
method: "POST",
body: getBeaconData(),
activateAfter: 60000, // 1 minute
});
} catch (e) {
if (e instanceof QuotaExceededError) {
// Handle the quota error
} else {
// Handle other errors
}
}
将 POST 请求延迟约一分钟并创建一个函数来检查是否已发送
const result = fetchLater("https://report.example.com", {
method: "POST",
body: JSON.stringify(myReport),
activateAfter: 60000 /* 1 minute */,
});
function checkIfFetched() {
return result.activated;
}
更新待处理请求
在此示例中,我们使用 AbortController 取消并重新创建请求
let beaconResult = null;
let beaconAbort = null;
function updateBeacon(data) {
const pending = !beaconResult || !beaconResult.activated;
if (pending && beaconAbort) {
beaconAbort.abort();
}
createBeacon(data);
}
function createBeacon(data) {
if (beaconResult && !beaconResult.activated) {
// Avoid creating duplicated beacon if the previous one is still pending.
return;
}
beaconAbort = new AbortController();
beaconResult = fetchLater({
url: data,
signal: beaconAbort.signal,
});
}
无效示例
以下任何对 fetchLater() 的调用都将抛出
// Only potentially trustworthy URLs are supported
fetchLater("http://untrusted.example.com");
// The length of the deferred request has to be known
fetchLater("https://origin.example.com", { body: someDynamicStream });
// Deferred fetching only works on active windows
const detachedWindow = iframe.contentWindow;
iframe.remove();
detachedWindow.fetchLater("https://origin.example.com");
规范
| 规范 |
|---|
| Fetch # deferred-fetch |
浏览器兼容性
加载中…