Workbox-Routing

Ein Service Worker kann Netzwerkanfragen für eine Seite abfangen. Sie kann dem Browser mit im Cache gespeicherten Inhalten, Inhalten aus dem Netzwerk oder Inhalten antworten, die vom Service Worker generiert wurden.

workbox-routing ist ein Modul, mit dem diese Anfragen einfach an verschiedene Funktionen weitergeleitet werden können, die Antworten liefern.

So wird das Routing durchgeführt

Wenn eine Netzwerkanfrage ein Service Worker-Abrufereignis verursacht, versucht workbox-routing, über die angegebenen Routen und Handler auf die Anfrage zu antworten.

Routingdiagramm für Arbeitsfelder

Die wichtigsten Punkte aus den obigen Angaben:

  • Die Methode einer Anfrage ist wichtig. Standardmäßig werden Routen für GET-Anfragen registriert. Wenn Sie andere Arten von Anfragen abfangen möchten, müssen Sie die Methode angeben.

  • Die Reihenfolge der Routenregistrierung ist wichtig. Wenn mehrere Routen registriert sind, die eine Anfrage verarbeiten können, wird die zuerst registrierte Route zum Antworten auf die Anfrage verwendet.

Es gibt verschiedene Möglichkeiten, eine Route zu registrieren. Sie können Callbacks, reguläre Ausdrücke oder Routeninstanzen verwenden.

Abgleich und Verarbeitung in Routen

Eine "Route" in der Arbeitsbox besteht aus nicht mehr als zwei Funktionen: einer Abgleichfunktion, um zu bestimmen, ob die Route einer Anfrage entsprechen soll, und einer Verarbeitungsfunktion, die die Anfrage verarbeiten und mit einer Antwort antworten sollte.

Workbox enthält einige Hilfsprogramme, die den Abgleich und die Verarbeitung für Sie durchführen. Wenn Sie jedoch jemals ein anderes Verhalten wünschen, ist das Schreiben einer benutzerdefinierten Abgleich- und Handler-Funktion die beste Option.

Einer Abgleich-Callback-Funktion werden ein ExtendableEvent-, Request- und ein URL-Objekt übergeben, das Sie abgleichen können, indem Sie einen Wahrheitswert zurückgeben. Für ein einfaches Beispiel könnten Sie den Abgleich mit einer bestimmten URL durchführen:

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

Die meisten Anwendungsfälle können durch Untersuchung / Tests von url oder request abgedeckt werden.

Eine Handler-Callback-Funktion erhält dasselbe ExtendableEvent-, Request- und URL-Objekt sowie einen params-Wert. Dies ist der Wert, der von der Abgleichfunktion zurückgegeben wird.

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,
  });
};

Dein Handler muss ein Promise zurückgeben, das zu einem Response aufgelöst wird. In diesem Beispiel verwenden wir async und await. Intern wird der Rückgabewert Response in ein Promise umgewandelt.

Sie können diese Callbacks so registrieren:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb);

Die einzige Einschränkung besteht darin, dass der „Übereinstimmung“-Callback synchron den Wahrheitswert zurückgeben muss. Sie können keine asynchronen Aufgaben ausführen. Der Grund dafür ist, dass Router synchron auf das Abrufereignis reagieren muss oder einen Durchfall auf andere Abrufereignisse zulassen muss.

Normalerweise verwendet der Callback „handler“ eine der von workbox-strategies bereitgestellten Strategien, wie hier gezeigt:

import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';

registerRoute(matchCb, new StaleWhileRevalidate());

Auf dieser Seite konzentrieren wir uns auf workbox-routing. Weitere Informationen zu diesen Strategien für Workbox-Strategien finden Sie hier.

Registrieren einer Route mit regulären Ausdrücken

Häufig wird ein regulärer Ausdruck anstelle eines Callbacks für Übereinstimmung verwendet. Mit Workbox ist dies ganz einfach:

import {registerRoute} from 'workbox-routing';

registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);

Bei Anfragen vom gleichen Ursprung stimmt dieser reguläre Ausdruck überein, solange die URL der Anfrage mit dem regulären Ausdruck übereinstimmt.

  • https://example.com/styles/main.css
  • https://example.com/styles/nested/file.css
  • https://example.com/nested/styles/directory.css

Bei ursprungsübergreifenden Anfragen müssen die regulären Ausdrücke jedoch mit dem Anfang der URL übereinstimmen. Der Grund dafür ist, dass Sie wahrscheinlich mit dem regulären Ausdruck new RegExp('/styles/.*\\.css') CSS-Dateien von Drittanbietern abgleichen möchten.

  • 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

Wenn Sie dieses Verhalten erwünscht haben, müssen Sie lediglich darauf achten, dass der reguläre Ausdruck mit dem Anfang der URL übereinstimmt. Wenn wir die Anfragen für https://cdn.third-party-site.com abgleichen möchten, können wir den regulären Ausdruck new RegExp('https://cdn\\.third-party-site\\.com.*/styles/.*\\.css') verwenden.

  • 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

Wenn Sie sowohl lokale als auch Drittanbieter-Objekte abgleichen möchten, können Sie am Anfang des regulären Ausdrucks einen Platzhalter verwenden. Dies sollte jedoch mit Vorsicht erfolgen, damit es in Ihrer Webanwendung nicht zu unerwartetem Verhalten kommt.

Registrieren einer Navigationsroute

Wenn Ihre Website eine Single-Page-App ist, können Sie einen NavigationRoute verwenden, um eine bestimmte Antwort auf alle Navigationsanfragen zurückzugeben.

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);

Immer wenn ein Nutzer Ihre Website im Browser aufruft, ist die Anfrage für die Seite eine Navigationsanfrage, die an die im Cache gespeicherte Seite /app-shell.html gesendet wird. Hinweis: Die Seite sollte über workbox-precaching oder durch deinen eigenen Installationsschritt im Cache gespeichert werden.

Standardmäßig werden damit alle Navigationsanfragen beantwortet. Wenn die Antwort auf eine Untergruppe von URLs eingeschränkt werden soll, können Sie mit den Optionen allowlist und denylist einschränken, welche Seiten dieser Route entsprechen.

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);

Es ist lediglich zu beachten, dass denylist gewinnt, wenn eine URL sowohl im allowlist- als auch im denylist-Element enthalten ist.

Standard-Handler festlegen

Wenn Sie einen „Handler“ für Anfragen angeben möchten, die mit keiner Route übereinstimmen, können Sie einen Standard-Handler festlegen.

import {setDefaultHandler} from 'workbox-routing';

setDefaultHandler(({url, event, params}) => {
  // ...
});

Catch-Handler einrichten

Wenn bei einer Ihrer Routen ein Fehler ausgegeben wird, können Sie mithilfe eines Catchall-Handlers die Erfassung und das Prinzip der Fehlertoleranz vornehmen.

import {setCatchHandler} from 'workbox-routing';

setCatchHandler(({url, event, params}) => {
  ...
});

Route für Nicht-GET-Anfragen definieren

Standardmäßig wird davon ausgegangen, dass alle Routen für GET-Anfragen vorgesehen sind.

Wenn Sie andere Anfragen weiterleiten möchten, z. B. eine POST-Anfrage, müssen Sie die Methode beim Registrieren der Route so definieren:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');

Router-Logging

Anhand der Logs von workbox-routing sollten Sie den Ablauf einer Anfrage ermitteln können. Diese Logs zeigen, welche URLs mit Workbox verarbeitet werden.

Routing-Logs

Wenn Sie ausführlichere Informationen benötigen, können Sie die Logebene auf debug festlegen, um Logs für Anfragen aufzurufen, die nicht vom Router verarbeitet werden. Weitere Informationen zum Festlegen der Logebene finden Sie in unserem Leitfaden zur Fehlerbehebung.

Routingnachrichten debuggen und protokollieren

Erweiterte Nutzung

Wenn Sie mehr Kontrolle darüber haben möchten, wann Anfragen an den Workbox Router gesendet werden, können Sie Ihre eigene Router-Instanz erstellen und deren Methode handleRequest() aufrufen, wenn Sie den Router zum Antworten auf eine Anfrage verwenden möchten.

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.
  }
});

Wenn Sie Router direkt verwenden, müssen Sie auch die Klasse Route oder eine der Erweiterungsklassen verwenden, um Routen zu registrieren.

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));

Typen

NavigationRoute

Mit NavigationRoute können Sie ganz einfach eine workbox-routing.Route erstellen, die den [Navigationsanfragen]des Browsers entsprichthttps://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests.

Es werden nur eingehende Anfragen abgeglichen, deren https://fetch.spec.whatwg.org/#concept-request-mode|mode auf navigate gesetzt ist.

Sie können diese Route optional nur auf einen Teil der Navigationsanfragen anwenden. Verwenden Sie dazu einen oder beide Parameter denylist und allowlist.

Attribute

  • Konstruktor

    void

    Wenn sowohl denylist als auch allowlist angegeben sind, hat denylist Vorrang und die Anfrage stimmt nicht mit dieser Route überein.

    Die regulären Ausdrücke in allowlist und denylist werden mit den verketteten Anteilen [pathname]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname und [search]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search der angeforderten URL abgeglichen.

    Hinweis: Diese RegExps können während der Navigation mit jeder Ziel-URL ausgewertet werden. Vermeiden Sie die Verwendung komplexer RegExps, da Ihre Nutzer sonst möglicherweise Verzögerungen beim Navigieren auf Ihrer Website feststellen.

    Die Funktion constructor sieht so aus:

    (handler: RouteHandler,options?: NavigationRouteMatchOptions)=> {...}

  • catchHandler
  • Übereinstimmung
  • method

    HTTPMethod

  • setCatchHandler

    void

    Die Funktion setCatchHandler sieht so aus:

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

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort aufgelöst wird.

NavigationRouteMatchOptions

Attribute

  • Zulassungsliste

    Regulärer Ausdruck[] optional

  • Sperrliste

    Regulärer Ausdruck[] optional

RegExpRoute

Mit RegExpRoute können Sie ganz einfach einen workbox-routing.Route auf Basis regulärer Ausdrücke erstellen.

Bei Anfragen vom selben Ursprung muss der RegExp nur mit einem Teil der URL übereinstimmen. Für Anfragen an Server von Drittanbietern müssen Sie einen regulären Ausdruck definieren, der mit dem Anfang der URL übereinstimmt.

Attribute

  • Konstruktor

    void

    Wenn der reguläre Ausdruck [Erfassungsgruppen]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references enthält, werden die erfassten Werte an das Argument workbox-routing~handlerCallback params übergeben.

    Die Funktion constructor sieht so aus:

    (regExp: RegExp,handler: RouteHandler,method?: HTTPMethod)=> {...}

    • regExp

      RegExp

      Regulärer Ausdruck für den Abgleich mit URLs

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort führt.

    • method

      HTTPMethod optional

  • catchHandler
  • Übereinstimmung
  • method

    HTTPMethod

  • setCatchHandler

    void

    Die Funktion setCatchHandler sieht so aus:

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

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort aufgelöst wird.

Route

Ein Route besteht aus einem Paar von Callback-Funktionen „match“ und „handler“. Der Callback „Match“ bestimmt, ob eine Route zum „Bearbeiten“ einer Anfrage verwendet werden soll, indem ein nicht falscher Wert zurückgegeben wird, sofern dies möglich ist. Der Callback „Handler“ wird bei einer Übereinstimmung aufgerufen und sollte ein Promise zurückgeben, das in ein Response aufgelöst wird.

Attribute

  • Konstruktor

    void

    Konstruktor für die Route-Klasse.

    Die Funktion constructor sieht so aus:

    (match: RouteMatchCallback,handler: RouteHandler,method?: HTTPMethod)=> {...}

    • Übereinstimmung

      Eine Callback-Funktion, die bestimmt, ob die Route einem bestimmten fetch-Ereignis entspricht, indem ein nicht falscher Wert zurückgegeben wird.

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das in eine Antwort aufgelöst wird.

    • method

      HTTPMethod optional

  • catchHandler
  • Übereinstimmung
  • method

    HTTPMethod

  • setCatchHandler

    void

    Die Funktion setCatchHandler sieht so aus:

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

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort aufgelöst wird.

Router

Der Router kann zur Verarbeitung einer FetchEvent mit einem oder mehreren workbox-routing.Route verwendet werden und mit einer Response antworten, wenn eine übereinstimmende Route vorhanden ist.

Wenn keine Route mit einer bestimmten Anfrage übereinstimmt, verwendet der Router einen "Standard"-Handler, sofern einer definiert ist.

Sollte die passende Route einen Fehler ausgeben, verwendet der Router einen „Catch“-Handler, falls definiert, um Probleme ordnungsgemäß zu beheben und mit einer Anfrage zu antworten.

Wenn eine Anfrage mit mehreren Routen übereinstimmt, wird die früheste registrierte Route zum Antworten auf die Anfrage verwendet.

Attribute

  • Konstruktor

    void

    Initialisiert einen neuen Router.

    Die Funktion constructor sieht so aus:

    ()=> {...}

  • Routen

    Map<HTTPMethodRoute[]>

  • addCacheListener

    void

    Fügt einen Nachrichtenereignis-Listener für URLs hinzu, die aus dem Fenster im Cache gespeichert werden sollen. Dies ist nützlich, um Ressourcen im Cache zu speichern, die auf der Seite geladen wurden, bevor der Service Worker mit der Steuerung der Seite begonnen hat.

    Die Nachrichtendaten, die vom Fenster gesendet werden, sollten folgendes Format haben. Das Array urlsToCache kann dabei aus URL-Strings oder einem Array aus URL-String und requestInit-Objekt bestehen (wie bei fetch()).

    {
      type: 'CACHE_URLS',
      payload: {
        urlsToCache: [
          './script1.js',
          './script2.js',
          ['./script3.js', {mode: 'no-cors'}],
        ],
      },
    }
    

    Die Funktion addCacheListener sieht so aus:

    ()=> {...}

  • addFetchListener

    void

    Fügt einen Abrufereignis-Listener hinzu, um auf Ereignisse zu reagieren, wenn eine Route der Ereignisanfrage entspricht.

    Die Funktion addFetchListener sieht so aus:

    ()=> {...}

  • findMatchingRoute

    void

    Prüft eine Anfrage und eine URL (und optional ein Ereignis) mit der Liste der registrierten Routen. Wenn eine Übereinstimmung vorliegt, werden die entsprechende Route zusammen mit allen durch die Übereinstimmung generierten Parametern zurückgegeben.

    Die Funktion findMatchingRoute sieht so aus:

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

    • Gibt zurück

      Objekt

      Ein Objekt mit den Attributen route und params. Sie werden ausgefüllt, wenn eine übereinstimmende Route gefunden wurde, oder andernfalls undefined.

  • handleRequest

    void

    Wenden Sie die Routingregeln auf ein FetchEvent-Objekt an, um eine Antwort vom Handler einer geeigneten Route zu erhalten.

    Die Funktion handleRequest sieht so aus:

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

    • Optionen

      Objekt

      • event

        ExtendableEvent

        Das Ereignis, das die Anfrage ausgelöst hat.

      • Request

        Anfragen

        Die zu verarbeitende Anfrage.

    • Gibt zurück

      Promise<Antwort>

      Ein Promise wird zurückgegeben, wenn eine registrierte Route die Anfrage verarbeiten kann. Wenn keine übereinstimmende Route und kein defaultHandler vorhanden ist, wird undefined zurückgegeben.

  • registerRoute

    void

    Registriert eine Route beim Router.

    Die Funktion registerRoute sieht so aus:

    (route: Route)=> {...}

    • Route

      Die Route, die registriert werden soll.

  • setCatchHandler

    void

    Wenn eine Route bei der Verarbeitung einer Anfrage einen Fehler ausgibt, wird diese handler aufgerufen und hat die Möglichkeit, eine Antwort zu liefern.

    Die Funktion setCatchHandler sieht so aus:

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

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort führt.

  • setDefaultHandler

    void

    Definieren Sie einen Standard-handler, der aufgerufen wird, wenn keine Routen explizit mit der eingehenden Anfrage übereinstimmen.

    Jede HTTP-Methode („GET“, „POST“ usw.) erhält einen eigenen Standard-Handler.

    Ohne einen Standard-Handler werden Anfragen ohne Übereinstimmung an das Netzwerk gesendet, als wäre kein Service Worker vorhanden.

    Die Funktion setDefaultHandler sieht so aus:

    (handler: RouteHandler,method?: HTTPMethod)=> {...}

    • Handler

      Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort führt.

    • method

      HTTPMethod optional

  • unregisterRoute

    void

    Hebt die Registrierung einer Route beim Router auf

    Die Funktion unregisterRoute sieht so aus:

    (route: Route)=> {...}

    • Route

      Die Route, deren Registrierung aufgehoben werden soll.

Methoden

registerRoute()

workbox-routing.registerRoute(
  capture: string|RegExp|RouteMatchCallback|Route,
  handler?: RouteHandler,
  method?: HTTPMethod,
)

Registrieren Sie auf einfache Weise einen RegExp, einen String oder eine Funktion mit einer Caching-Strategie auf einer Singleton-Router-Instanz.

Diese Methode generiert bei Bedarf eine Route und ruft workbox-routing.Router#registerRoute auf.

Parameters

  • Erfassung

    Ist der Erfassungsparameter ein Route, werden alle anderen Argumente ignoriert.

  • Handler

    RouteHandler optional

  • method

    HTTPMethod optional

Rückgaben

  • Die generierte Route.

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

Wenn eine Route bei der Verarbeitung einer Anfrage einen Fehler ausgibt, wird diese handler aufgerufen und hat die Möglichkeit, eine Antwort zu liefern.

Parameters

  • Handler

    Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort führt.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

Definieren Sie einen Standard-handler, der aufgerufen wird, wenn keine Routen explizit mit der eingehenden Anfrage übereinstimmen.

Ohne einen Standard-Handler werden Anfragen ohne Übereinstimmung an das Netzwerk gesendet, als wäre kein Service Worker vorhanden.

Parameters

  • Handler

    Eine Callback-Funktion, die ein Promise-Objekt zurückgibt, das zu einer Antwort führt.