工作箱路由

Service Worker 可以攔截網頁的網路要求。可能會回應 含有快取內容的瀏覽器、網路內容或 實作在 Service Worker 中

workbox-routing 是一個模組,可讓您輕鬆「規劃路線」對這些要求 提供回應的不同函式

轉送的執行方式

當網路要求導致 Service Worker 擷取事件時,workbox-routing 會嘗試使用提供的路徑和處理常式來回應要求。

Workbox 轉送圖表

上述需要注意的重點如下:

  • 要求的方法非常重要。根據預設,路徑會註冊於 GET 要求。若要攔截其他類型的要求,您需要 來指定方法

  • 路徑登錄的順序相當重要。如果有多個路徑 可處理要求的路徑,且先註冊的路徑 就會用於回應要求

有幾種方式可以註冊路徑:使用回呼、 或轉送執行個體

路徑介面集的比對和處理

「路線」只是工作箱中存在的一件事,就是「比對」函式 用於判斷路線是否應與要求相符,且「處理」則都是在呼叫函式中設定 ,負責處理要求並回應要求

Workbox 隨附部分輔助程式,可以執行 但如果您需要不同的行為模式 自訂比對和處理常式函式就是最佳選擇

A 罩杯 比對回呼函式 會傳遞 ExtendableEventRequest,以及 URL 物件即可 來比對結果。舉個簡單的例子,您可以將 特定網址,如下所示:

const matchCb = ({url, request, event}) => {
  return url.pathname === '/special/url';
};

在檢查 / 測試 urlrequest

A 罩杯 處理常式回呼函式 也會提供 ExtendableEventRequestURL 物件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 asyncawait。 實際上,傳回的 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 或 自己的安裝步驟)。

根據預設,這會回應「所有」導覽要求。如果您想 您可以使用 allowlistdenylist 選項,用於限制哪些網頁與這條路線相符。

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 將勝出 allowlistdenylist

設定預設處理常式

如果要提供「處理常式」不符合路線的要求時, 可以設定預設處理常式

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

您可以視情況將路線套用至部分導覽要求 使用 denylistallowlist 參數,或兩者皆用。

屬性

  • 建構函式

    void

    如果同時提供 denylistallowlistdenylist 會 ,且此要求將不會與此路徑相符。

    allowlistdenylist 中的規則運算式 與串連的向量 [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) => {...}

  • catchHandler
  • method

    HTTPMethod

  • setCatchHandler

    void

    setCatchHandler 函式如下所示:

    (handler: RouteHandler) => {...}

    • handler

      回呼 會傳回 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 (選用)

  • catchHandler
  • method

    HTTPMethod

  • setCatchHandler

    void

    setCatchHandler 函式如下所示:

    (handler: RouteHandler) => {...}

    • handler

      回呼 會傳回 Promise 解析至回應的函式

Route

Route 包含一組回呼函式「match」和「handler」 「match」(相符)回呼會決定是否要使用路線來「處理」換 傳回不偽值的要求「handler」回呼 如果有相符項目,應會傳回可解析的 Promise 至 Response

屬性

Router

路由器可用於處理FetchEvent使用 workbox-routing.Route,如果發生以下狀況,則回應 Response 找到相符的路徑

如果沒有符合指定要求的路徑,路由器會使用「default」 處理常式。

如果相符的路徑擲回錯誤,路由器會使用「catch」 處理常式 (如果已定義該處理常式以便妥善處理問題,然後以 。

如果要求與多條路線相符,則「最早」的登錄路徑會 回應要求

屬性

  • 建構函式

    void

    初始化新的路由器。

    constructor 函式如下所示:

    () => {...}

  • 路徑

    Map&lt;HTTPMethodRoute[]&gt;

  • 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

      物件

      具有 routeparams 屬性的物件。 如果找到相符的路線或 undefined,則填入這些路徑。 反之。

  • handleRequest

    void

    將轉送規則套用至 FetchEvent 物件,從 適用的 Route 處理常式

    handleRequest 函式如下所示:

    (options: object) => {...}

    • 選項

      物件

      • 活動

        ExtendableEvent

        觸發 請求。

      • 申請。

        要求

        要處理的要求。

    • returns

      Promise&lt;Response&gt;

      如果 可以使用已註冊的路徑處理要求如果沒有相符的項目 路線沒有 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 (選用)

傳回

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

如果路徑在處理要求時擲回錯誤,此 handler ,並提供回應機會。

參數

  • handler

    回呼 函式,會傳回 Promise,並產生回應。

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

定義未明確路徑時呼叫的預設 handler 比對收到的要求

如果沒有預設處理常式,不相符的要求就會針對 就好像沒有 Service Worker 一樣

參數

  • handler

    回呼 函式,會傳回 Promise,並產生回應。