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 |
瀏覽器相容性
載入中…