Service Worker 可以攔截網頁的網路要求。可能會回應 含有快取內容的瀏覽器、網路內容或 實作在 Service Worker 中
workbox-routing
是一個模組,可讓您輕鬆「規劃路線」對這些要求
提供回應的不同函式
轉送的執行方式
當網路要求導致 Service Worker 擷取事件時,workbox-routing
會嘗試使用提供的路徑和處理常式來回應要求。
上述需要注意的重點如下:
要求的方法非常重要。根據預設,路徑會註冊於
GET
要求。若要攔截其他類型的要求,您需要 來指定方法路徑登錄的順序相當重要。如果有多個路徑 可處理要求的路徑,且先註冊的路徑 就會用於回應要求
有幾種方式可以註冊路徑:使用回呼、 或轉送執行個體
路徑介面集的比對和處理
「路線」只是工作箱中存在的一件事,就是「比對」函式 用於判斷路線是否應與要求相符,且「處理」則都是在呼叫函式中設定 ,負責處理要求並回應要求
Workbox 隨附部分輔助程式,可以執行 但如果您需要不同的行為模式 自訂比對和處理常式函式就是最佳選擇
A 罩杯
比對回呼函式
會傳遞
ExtendableEvent
、
Request
,以及
URL
物件即可
來比對結果。舉個簡單的例子,您可以將
特定網址,如下所示:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
在檢查 / 測試 url
或
request
。
A 罩杯
處理常式回呼函式
也會提供
ExtendableEvent
、
Request
和
URL
物件與
params
值,也就是「match」傳回的值函式。
const handlerCb = async ({url, request, event, params}) => {
const response = await fetch(request);
const responseBody = await response.text();
return new Response(`${responseBody} <!-- Look Ma. Added Content. -->`, {
headers: response.headers,
});
};
您的處理常式必須傳回可解析為 Response
的承諾。在本
也就是使用 Kubernetes
async
和 await
。
實際上,傳回的 Response
值會包裝在承諾中。
您可以註冊這些回呼,如下所示:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
唯一的限制是回呼必須同步傳回 Tuthy
這個值,就無法執行任何非同步工作。原因是
Router
必須同步回應擷取事件,或允許下降
其他擷取事件
通常為「handler」回呼會使用所提供的其中一項策略 透過 workbox-strategies,如下所示:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
本頁面將著重說明 workbox-routing
,但您可以
進一步瞭解這些 Workbox 策略。
如何註冊規則運算式路徑
常見的做法是使用規則運算式,而不要使用「比對」回呼。 使用 Workbox 可以輕鬆實作,如下所示:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
對於 相同來源、 只要要求網址與 規則運算式
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
不過,如果是跨來源要求,規則運算式
必須與網址開頭相符。之所以會這樣
此時,規則運算式為 new RegExp('/styles/.*\\.css')
的機率可能會較低
用於比對第三方 CSS 檔案
- https://cdn.third-party-site.com/styles/main.css
- https://cdn.third-party-site.com/styles/nested/file.css
- https://cdn.third-party-site.com/nested/styles/directory.css
如果您要「確實」這種行為,只要確保正常運作,
運算式會比對網址的開頭。若要比對
https://cdn.third-party-site.com
要求,我們可以使用
運算式 new RegExp('https://cdn\\.third-party-site\\.com.*/styles/.*\\.css')
。
- https://cdn.third-party-site.com/styles/main.css
- https://cdn.third-party-site.com/styles/nested/file.css
- https://cdn.third-party-site.com/nested/styles/directory.css
如果想同時比對本機和第三方,可以使用萬用字元 加到規則運算式的開頭,不過使用時請務必謹慎 以避免在您的網路應用程式中造成非預期的行為。
如何註冊導航路徑
如果您的網站是單頁應用程式,您可以使用
NavigationRoute
到
傳回所有
導航要求。
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler);
registerRoute(navigationRoute);
每當使用者在瀏覽器中前往你的網站時,網頁的要求就會
為瀏覽要求,且將提供快取網頁 /app-shell.html
。
(注意:系統應透過 workbox-precaching
或
自己的安裝步驟)。
根據預設,這會回應「所有」導覽要求。如果您想
您可以使用 allowlist
和 denylist
選項,用於限制哪些網頁與這條路線相符。
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
// This assumes /app-shell.html has been precached.
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [new RegExp('/blog/')],
denylist: [new RegExp('/blog/restricted/')],
});
registerRoute(navigationRoute);
唯一要注意的是,如果網址同時存在於兩個位置,denylist
將勝出
allowlist
和 denylist
。
設定預設處理常式
如果要提供「處理常式」不符合路線的要求時, 可以設定預設處理常式
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
設定擷取處理常式
如果有任何路徑擲回錯誤,您可以擷取並 設定擷取處理常式以優雅降級。
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
定義非 GET 要求的路徑
根據預設,所有路徑皆適用於 GET
要求。
如要轉送其他要求 (例如 POST
要求),您需要
定義方法,以在註冊路徑時定義方法,如下所示:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
路由器記錄
您應能使用
workbox-routing
:醒目顯示目前正在處理的網址
。
如果您需要更詳細的資訊,可以將記錄層級設為 debug
為
查看非由路由器處理的要求記錄。請參閱
偵錯指南瞭解詳情
或是設定記錄層級
進階用法
如要進一步控管指派 Workbox 路由器的時機
您就能自行建立
Router
執行個體和呼叫
現在是handleRequest()
方法。
import {Router} from 'workbox-routing';
const router = new Router();
self.addEventListener('fetch', event => {
const {request} = event;
const responsePromise = router.handleRequest({
event,
request,
});
if (responsePromise) {
// Router found a route to handle the request.
event.respondWith(responsePromise);
} else {
// No route was found to handle the request.
}
});
直接使用 Router
時,您也需要使用 Route
類別,
或任何擴充類別註冊路徑。
import {Route, RegExpRoute, NavigationRoute, Router} from 'workbox-routing';
const router = new Router();
router.registerRoute(new Route(matchCb, handlerCb));
router.registerRoute(new RegExpRoute(new RegExp(...), handlerCb));
router.registerRoute(new NavigationRoute(handlerCb));
類型
NavigationRoute
您可利用 NavigationRoute 輕鬆建立
workbox-routing.Route
與瀏覽器相符
[導航要求]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests
。
只會比對符合下列條件的傳入要求:
https://fetch.spec.whatwg.org/#concept-request-mode|mode
已設為 navigate
。
您可以視情況將路線套用至部分導覽要求
使用 denylist
和 allowlist
參數,或兩者皆用。
屬性
-
void
如果同時提供
denylist
和allowlist
,denylist
會 ,且此要求將不會與此路徑相符。allowlist
和denylist
中的規則運算式 與串連的向量 [pathname
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname
和 [search
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search
部分的值。注意:系統在評估這些規則運算式時,可能會根據每個到達網頁網址進行評估, 以及導覽功能避免使用 複雜規則運算式 否則使用者瀏覽網站時可能會延遲
constructor
函式如下所示:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
回呼 函式,會傳回 Promise,並產生回應。
-
-
HTTPMethod
-
void
setCatchHandler
函式如下所示:(handler: RouteHandler) => {...}
-
回呼 會傳回 Promise 解析至回應的函式
-
NavigationRouteMatchOptions
屬性
-
規則運算式 [] 選填
-
規則運算式 [] 選填
RegExpRoute
RegExpRoute 能讓您輕鬆建立以規則運算式為基礎的
workbox-routing.Route
。
針對相同來源的要求,RegExp 只需與部分網址相符。適用對象 對第三方伺服器的要求,您必須定義符合 開頭。
屬性
-
建構函式
void
如果規則運算式中包含 [擷取群組]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
, 擷取的值將傳遞至workbox-routing~handlerCallback
params
引數。constructor
函式如下所示:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
用於比對網址的規則運算式。
-
handler
回呼 函式,會傳回 Promise,並產生回應。
-
method
HTTPMethod (選用)
-
returns
-
-
catchHandler
-
handler
-
method
HTTPMethod
-
setCatchHandler
void
setCatchHandler
函式如下所示:(handler: RouteHandler) => {...}
-
handler
回呼 會傳回 Promise 解析至回應的函式
-
Route
Route
包含一組回呼函式「match」和「handler」
「match」(相符)回呼會決定是否要使用路線來「處理」換
傳回不偽值的要求「handler」回呼
如果有相符項目,應會傳回可解析的 Promise
至 Response
。
屬性
-
建構函式
void
Route 類別的建構函式。
constructor
函式如下所示:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
判斷路線是否符合指定
fetch
事件。 -
handler
回呼 函式,會傳回 Promise 解析至回應。
-
method
HTTPMethod (選用)
-
returns
-
-
catchHandler
-
handler
-
method
HTTPMethod
-
setCatchHandler
void
setCatchHandler
函式如下所示:(handler: RouteHandler) => {...}
-
handler
回呼 會傳回 Promise 解析至回應的函式
-
Router
路由器可用於處理FetchEvent
使用
workbox-routing.Route
,如果發生以下狀況,則回應 Response
找到相符的路徑
如果沒有符合指定要求的路徑,路由器會使用「default」 處理常式。
如果相符的路徑擲回錯誤,路由器會使用「catch」 處理常式 (如果已定義該處理常式以便妥善處理問題,然後以 。
如果要求與多條路線相符,則「最早」的登錄路徑會 回應要求
屬性
-
建構函式
void
初始化新的路由器。
constructor
函式如下所示:() => {...}
-
returns
-
-
路徑
Map<HTTPMethodRoute[]>
-
addCacheListener
void
新增訊息事件監聽器,要求從視窗快取網址。 以便在載入檔案前,先快取網頁載入的資源 Service Worker 已開始控管。
從視窗傳送的訊息資料應如下所示。 其中的
urlsToCache
陣列可能包含網址字串或 網址字串 +requestInit
物件 (與傳送至fetch()
的物件相同)。{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
addCacheListener
函式如下所示:() => {...}
-
addFetchListener
void
新增擷取事件監聽器,以在路線符合時回應事件 事件的請求。
addFetchListener
函式如下所示:() => {...}
-
findMatchingRoute
void
檢查要求和網址 (也可視需要針對事件清單) 如果有相符的記錄,則會傳回 和任何比對所產生的參數
findMatchingRoute
函式如下所示:(options: RouteMatchCallbackOptions) => {...}
-
returns
物件
具有
route
和params
屬性的物件。 如果找到相符的路線或undefined
,則填入這些路徑。 反之。
-
-
handleRequest
void
將轉送規則套用至 FetchEvent 物件,從 適用的 Route 處理常式
handleRequest
函式如下所示:(options: object) => {...}
-
選項
物件
-
活動
ExtendableEvent
觸發 請求。
-
申請。
要求
要處理的要求。
-
-
returns
Promise<Response>
如果 可以使用已註冊的路徑處理要求如果沒有相符的項目 路線沒有
defaultHandler
,會傳回undefined
。
-
-
registerRoute
void
向路由器註冊路徑。
registerRoute
函式如下所示:(route: Route) => {...}
-
路徑
要註冊的路徑。
-
-
setCatchHandler
void
如果路徑在處理要求時擲回錯誤,此
handler
,並提供回應機會。setCatchHandler
函式如下所示:(handler: RouteHandler) => {...}
-
handler
回呼 函式,會傳回 Promise,並產生回應。
-
-
setDefaultHandler
void
定義未明確路徑時呼叫的預設
handler
比對收到的要求每個 HTTP 方法 (「GET」、「POST」等) 都會取得自己的預設處理常式。
如果沒有預設處理常式,不相符的要求就會針對 就好像沒有 Service Worker 一樣
setDefaultHandler
函式如下所示:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
handler
回呼 函式,會傳回 Promise,並產生回應。
-
method
HTTPMethod (選用)
-
-
unregisterRoute
void
取消註冊路由器的路徑。
unregisterRoute
函式如下所示:(route: Route) => {...}
-
路徑
要取消註冊的路徑。
-
方法
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
使用快取輕鬆註冊規則運算式、字串或函式 一個是單例模式路由器執行個體的策略
這個方法會視需求產生路徑
呼叫 workbox-routing.Router#registerRoute
。
參數
-
擷取
string |規則運算式 |RouteMatchCallback |路線
如果擷取參數是
Route
,系統將忽略所有其他引數。 -
handler
RouteHandler (選用)
-
method
HTTPMethod (選用)
傳回
-
產生的
Route
。
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
如果路徑在處理要求時擲回錯誤,此 handler
,並提供回應機會。
參數
-
handler
回呼 函式,會傳回 Promise,並產生回應。
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
定義未明確路徑時呼叫的預設 handler
比對收到的要求
如果沒有預設處理常式,不相符的要求就會針對 就好像沒有 Service Worker 一樣
參數
-
handler
回呼 函式,會傳回 Promise,並產生回應。