ServiceWorkerGlobalScope: fetch 事件
注意:此功能仅在 Service Workers 中可用。
ServiceWorkerGlobalScope 接口的 fetch 事件在主应用程序线程发出网络请求时,在 Service Worker 的全局作用域中触发。它允许 Service Worker 拦截网络请求并发送自定义响应(例如,从本地缓存)。
此事件不可取消,也不会冒泡。
语法
在诸如 addEventListener() 之类的方法中使用事件名称,或设置事件处理程序属性。
addEventListener("fetch", (event) => { })
onfetch = (event) => { }
描述
当主应用程序线程发出网络请求时,fetch 事件在 Service Worker 的全局作用域中触发。这不仅包括主线程中显式的 fetch() 调用,还包括浏览器在页面导航后加载页面和子资源(如 JavaScript、CSS 和图像)的隐式网络请求。
事件处理程序会接收一个 FetchEvent 对象,该对象提供对请求的访问,请求是一个 Request 实例。
FetchEvent 还提供了一个 respondWith() 方法,该方法接受一个 Response(或解析为 Response 的 Promise)作为参数。这使得 Service Worker 事件处理程序能够提供返回给主线程请求的响应。
例如,Service Worker 可以返回:
- 从
Cache接口检索到的本地缓存响应。 - Service Worker 使用诸如
Response.json()等方法或Response()构造函数合成的响应。 - 使用
Response.error()方法的网络错误。这将导致fetch()调用被拒绝。
对于给定的请求,respondWith() 方法只能调用一次。如果添加了多个 fetch 事件监听器,它们将按照注册顺序调用,直到其中一个调用了 respondWith()。
respondWith() 方法必须同步调用:也就是说,你不能在 then 处理程序中调用它。
通常,fetch 事件处理程序会根据请求的特征(如其 URL)执行不同的策略。
function strategy1() {
return fetch("picnic.jpg");
}
function strategy2() {
return Response.error();
}
const pattern1 = /^\/salamander/;
const pattern2 = /^\/lizard/;
self.addEventListener("fetch", (event) => {
const url = new URL(event.request.url);
if (pattern1.test(url.pathname)) {
event.respondWith(strategy1());
} else if (pattern2.test(url.pathname)) {
event.respondWith(strategy2());
}
});
如果在处理程序中未调用 respondWith(),则用户代理会自动发出原始网络请求。例如,在上面的代码中,所有不匹配 pattern1 或 pattern2 的请求都像 Service Worker 不存在一样发出。
事件类型
一个 FetchEvent。
示例
缓存后备网络
此 fetch 事件处理程序首先尝试在缓存中查找响应。如果找到响应,则返回缓存的响应。否则,它尝试从网络获取资源。
async function cacheThenNetwork(request) {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log("Found response in cache:", cachedResponse);
return cachedResponse;
}
console.log("Falling back to network");
return fetch(request);
}
self.addEventListener("fetch", (event) => {
console.log(`Handling fetch event for ${event.request.url}`);
event.respondWith(cacheThenNetwork(event.request));
});
仅缓存
此 fetch 事件处理程序对脚本和样式表实现“仅缓存”策略。如果请求的 destination 属性为 "script" 或 "style",则处理程序仅在缓存中查找,如果未找到响应则返回错误。所有其他请求都将通过网络。
async function cacheOnly(request) {
const cachedResponse = await caches.match(request);
if (cachedResponse) {
console.log("Found response in cache:", cachedResponse);
return cachedResponse;
}
return Response.error();
}
self.addEventListener("fetch", (event) => {
if (
event.request.destination === "script" ||
event.request.destination === "style"
) {
event.respondWith(cacheOnly(event.request));
}
});
规范
| 规范 |
|---|
| Service Workers # dom-serviceworkerglobalscope-onfetch |
浏览器兼容性
加载中…