werkdoos-routing

Een servicemedewerker kan netwerkverzoeken voor een pagina onderscheppen. Het kan op de browser reageren met inhoud in de cache, inhoud van het netwerk of inhoud die door de servicemedewerker is gegenereerd.

workbox-routing is een module die het gemakkelijk maakt om deze verzoeken te "routeren" naar verschillende functies die antwoorden bieden.

Hoe routering wordt uitgevoerd

Wanneer een netwerkverzoek een ophaalgebeurtenis van een servicemedewerker veroorzaakt, probeert workbox-routing op het verzoek te reageren met behulp van de opgegeven routes en handlers.

Workbox-routeringsdiagram

De belangrijkste dingen om op te merken uit het bovenstaande zijn:

  • De wijze van aanvragen is belangrijk. Standaard worden routes geregistreerd voor GET aanvragen. Als u andere typen verzoeken wilt onderscheppen, moet u de methode opgeven.

  • De volgorde van de Routeregistratie is belangrijk. Als er meerdere Routes zijn geregistreerd die een verzoek kunnen afhandelen, wordt de Route die als eerste is geregistreerd gebruikt om op het verzoek te reageren.

Er zijn een paar manieren om een ​​route te registreren: u kunt callbacks, reguliere expressies of Route-instanties gebruiken.

Matchen en verwerken in routes

Een "route" in de workbox bestaat uit niets meer dan twee functies: een "matching"-functie om te bepalen of de route moet overeenkomen met een verzoek en een "handling"-functie, die het verzoek moet afhandelen en moet reageren met een antwoord.

Workbox wordt geleverd met een aantal helpers die de matching en afhandeling voor u uitvoeren, maar als u ooit merkt dat u ander gedrag wilt, is het schrijven van een aangepaste match- en handlerfunctie de beste optie.

Er wordt een match-callback-functie doorgegeven aan ExtendableEvent , Request en een URL object dat u kunt matchen door een waarheidsgetrouwe waarde te retourneren. Voor een eenvoudig voorbeeld kunt u een specifieke URL als volgt matchen:

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

De meeste gebruiksscenario's kunnen worden gedekt door de url of het request te onderzoeken/testen.

Een handler-callback-functie krijgt hetzelfde ExtendableEvent , Request en URL object samen met een params waarde, de waarde die wordt geretourneerd door de functie "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,
  });
};

Uw begeleider moet een belofte teruggeven die uitmondt in een Response . In dit voorbeeld gebruiken we async en await . Onder de motorkap wordt de Response verpakt in een belofte.

U kunt deze terugbelverzoeken als volgt registreren:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb);

De enige beperking is dat de "match" callback synchroon een waarheidsgetrouwe waarde moet retourneren, je kunt geen asynchroon werk uitvoeren. De reden hiervoor is dat de Router synchroon moet reageren op de ophaalgebeurtenis of moet toestaan ​​dat er wordt doorgeschakeld naar andere ophaalgebeurtenissen.

Normaal gesproken zou de callback van de "handler" een van de strategieën gebruiken die door workbox-strategieën worden geboden, zoals:

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

registerRoute(matchCb, new StaleWhileRevalidate());

Op deze pagina concentreren we ons op workbox-routing , maar u kunt meer over deze strategieën leren op workbox-strategieën .

Hoe u een reguliere expressieroute registreert

Een veel voorkomende praktijk is het gebruik van een reguliere expressie in plaats van een 'match'-callback. Workbox maakt dit eenvoudig als volgt te implementeren:

import {registerRoute} from 'workbox-routing';

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

Voor verzoeken van dezelfde oorsprong komt deze reguliere expressie overeen zolang de URL van het verzoek overeenkomt met de reguliere expressie.

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

Voor cross-origin-verzoeken moeten reguliere expressies echter overeenkomen met het begin van de URL . De reden hiervoor is dat het onwaarschijnlijk is dat u met een reguliere expressie new RegExp('/styles/.*\\.css') CSS-bestanden van derden wilde matchen.

  • 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

Als u dit gedrag toch wilt, hoeft u er alleen maar voor te zorgen dat de reguliere expressie overeenkomt met het begin van de URL. Als we de verzoeken voor https://cdn.third-party-site.com willen matchen, kunnen we de reguliere expressie 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

Als u zowel lokale als externe partijen wilt matchen, kunt u een jokerteken gebruiken aan het begin van uw reguliere expressie, maar dit moet met de nodige voorzichtigheid gebeuren om ervoor te zorgen dat dit geen onverwacht gedrag in uw web-app veroorzaakt.

Een navigatieroute registreren

Als uw site een app met één pagina is, kunt u een NavigationRoute gebruiken om een ​​specifiek antwoord te retourneren voor alle navigatieverzoeken .

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

Wanneer een gebruiker in de browser naar uw site gaat, is het verzoek voor de pagina een navigatieverzoek en wordt de pagina /app-shell.html in de cache weergegeven. (Opmerking: u moet de pagina in de cache laten opslaan via workbox-precaching of via uw eigen installatiestap.)

Standaard reageert dit op alle navigatieverzoeken. Als u wilt beperken dat er op een subset van URL's wordt gereageerd, kunt u de opties voor de allowlist en denylist gebruiken om te beperken welke pagina's met deze route overeenkomen.

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

Het enige dat u moet weten, is dat de denylist wint als een URL zowel op de allowlist als op denylist staat.

Stel een standaardhandler in

Als u een "handler" wilt opgeven voor verzoeken die niet overeenkomen met een route, kunt u een standaardhandler instellen.

import {setDefaultHandler} from 'workbox-routing';

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

Stel een catch-handler in

Als een van je routes een fout oplevert, kun je op een elegante manier vastleggen en degraderen door een catch-handler in te stellen.

import {setCatchHandler} from 'workbox-routing';

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

Een route definiëren voor niet-GET-verzoeken

Er wordt standaard aangenomen dat alle routes bedoeld zijn voor GET aanvragen.

Als u andere verzoeken wilt routeren, zoals een POST verzoek, moet u de methode als volgt definiëren bij het registreren van de route:

import {registerRoute} from 'workbox-routing';

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

Routerregistratie

U zou de stroom van een verzoek moeten kunnen bepalen met behulp van de logbestanden van workbox-routing , die aangeven welke URL's via Workbox worden verwerkt.

Routeringslogboeken

Als u uitgebreidere informatie nodig heeft, kunt u het logniveau instellen op debug om logbestanden te bekijken van verzoeken die niet door de router zijn afgehandeld. Zie onze foutopsporingsgids voor meer informatie over het instellen van het logniveau.

Foutopsporing en log-routeringsberichten

Geavanceerd gebruik

Als u meer controle wilt hebben over wanneer de Workbox Router verzoeken krijgt, kunt u uw eigen Router instantie maken en de handleRequest() -methode ervan aanroepen wanneer u de router wilt gebruiken om op een verzoek te reageren.

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

Wanneer u de Router rechtstreeks gebruikt, moet u ook de klasse Route of een van de uitbreidingsklassen gebruiken om routes te registreren.

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

Soorten

NavigationRoute

NavigationRoute maakt het eenvoudig om een workbox-routing.Route te maken die overeenkomt met browser [navigatieverzoeken] https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests .

Het komt alleen overeen met inkomende verzoeken waarvan https://fetch.spec.whatwg.org/#concept-request-mode|mode is ingesteld om te navigate .

Optioneel kunt u deze route alleen toepassen op een subset van navigatieverzoeken door een of beide parameters voor de denylist en allowlist te gebruiken.

Eigenschappen

  • bouwer

    leegte

    Als zowel denylist als allowlist zijn opgegeven, heeft de denylist voorrang en komt het verzoek niet overeen met deze route.

    De reguliere expressies in allowlist en denylist worden vergeleken met de aaneengeschakelde [ pathname ] https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname en [ search ] https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search van de gevraagde URL.

    Opmerking : deze RegExps kunnen tijdens een navigatie worden geëvalueerd aan de hand van elke bestemmings-URL. Vermijd het gebruik van complexe RegExps , anders kunnen uw gebruikers vertragingen ondervinden bij het navigeren op uw site.

    De constructor ziet er als volgt uit:

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

  • catchHandler

    RouteHandlerObject optioneel

  • begeleider
  • overeenkomst
  • methode

    HTTP-methode

  • setCatchHandler

    leegte

    De setCatchHandler -functie ziet er als volgt uit:

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

    • begeleider

      Een callback-functie die een belofte retourneert die wordt omgezet in een antwoord

NavigationRouteMatchOptions

Eigenschappen

  • toelatingslijst

    RegExp[] optioneel

  • weigeringslijst

    RegExp[] optioneel

RegExpRoute

RegExpRoute maakt het eenvoudig om op reguliere expressies gebaseerde workbox-routing.Route te maken.

Voor verzoeken van dezelfde oorsprong hoeft de RegExp slechts een deel van de URL te matchen. Voor verzoeken tegen servers van derden moet u een RegExp definiëren die overeenkomt met het begin van de URL.

Eigenschappen

  • bouwer

    leegte

    Als de reguliere expressie [capture groups] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references bevat, worden de vastgelegde waarden doorgegeven aan de workbox-routing~handlerCallback params argument.

    De constructor ziet er als volgt uit:

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

    • regExp

      RegExp

      De reguliere expressie die moet matchen met URL's.

    • begeleider

      Een callback-functie die een belofte retourneert, resulterend in een antwoord.

    • methode

      HTTPMethode optioneel

  • catchHandler

    RouteHandlerObject optioneel

  • begeleider
  • overeenkomst
  • methode

    HTTP-methode

  • setCatchHandler

    leegte

    De setCatchHandler functie ziet er als volgt uit:

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

    • begeleider

      Een callback-functie die een belofte retourneert die wordt omgezet in een antwoord

Route

Een Route bestaat uit een paar callback-functies, "match" en "handler". De "match"-callback bepaalt of een route moet worden gebruikt om een ​​verzoek te "afhandelen" door, indien mogelijk, een niet-valse waarde te retourneren. De "handler" callback wordt aangeroepen als er een match is en zou een Promise moeten retourneren die in een Response resulteert.

Eigenschappen

  • bouwer

    leegte

    Constructor voor routeklasse.

    De constructor ziet er als volgt uit:

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

    • overeenkomst

      Een callback-functie die bepaalt of de route overeenkomt met een bepaalde fetch door een niet-valse waarde te retourneren.

    • begeleider

      Een callback-functie die een belofte retourneert die wordt omgezet in een antwoord.

    • methode

      HTTPMethode optioneel

  • catchHandler

    RouteHandlerObject optioneel

  • begeleider
  • overeenkomst
  • methode

    HTTP-methode

  • setCatchHandler

    leegte

    De setCatchHandler functie ziet er als volgt uit:

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

    • begeleider

      Een callback-functie die een belofte retourneert die wordt omgezet in een antwoord

Router

De router kan worden gebruikt om een FetchEvent te verwerken met behulp van een of meer workbox-routing.Route , en reageert met een Response als er een overeenkomende route bestaat.

Als geen enkele route overeenkomt met een bepaald verzoek, zal de router een "standaard" handler gebruiken, als deze is gedefinieerd.

Mocht de overeenkomende route een fout opleveren, dan zal de router een "catch"-handler gebruiken, als deze is gedefinieerd, om problemen netjes af te handelen en te reageren met een verzoek.

Als een aanvraag overeenkomt met meerdere routes, wordt de vroegst geregistreerde route gebruikt om op de aanvraag te reageren.

Eigenschappen

  • bouwer

    leegte

    Initialiseert een nieuwe router.

    De constructor ziet er als volgt uit:

    () => {...}

  • trajecten

    Breng<HTTPMethodRoute[]> in kaart

  • addCacheListener

    leegte

    Voegt een berichtgebeurtenislistener toe voor URL's die vanuit het venster in de cache moeten worden opgeslagen. Dit is handig om bronnen in de cache op te slaan die op de pagina zijn geladen voordat de servicemedewerker deze begon te beheren.

    Het formaat van de berichtgegevens die vanuit het venster worden verzonden, moet als volgt zijn. Waar de urlsToCache -array kan bestaan ​​uit URL-tekenreeksen of een reeks URL-tekenreeksen + requestInit object (hetzelfde als u zou doorgeven aan fetch() ).

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

    De addCacheListener functie ziet er als volgt uit:

    () => {...}

  • addFetchListener

    leegte

    Voegt een ophaalgebeurtenislistener toe om op gebeurtenissen te reageren wanneer een route overeenkomt met het verzoek van de gebeurtenis.

    De addFetchListener functie ziet er als volgt uit:

    () => {...}

  • vindMatchingRoute

    leegte

    Controleert een verzoek en URL (en optioneel een gebeurtenis) aan de hand van de lijst met geregistreerde routes, en retourneert, als er een match is, de corresponderende route samen met eventuele parameters die door de match zijn gegenereerd.

    De findMatchingRoute -functie ziet er als volgt uit:

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

    • retourneert

      voorwerp

      Een object met route en params eigenschappen. Ze worden gevuld als er een overeenkomende route is gevonden of als deze op een andere manier undefined .

  • handvatVerzoek

    leegte

    Pas de routeringsregels toe op een FetchEvent-object om een ​​antwoord te krijgen van een geschikte Route-handler.

    De handleRequest functie ziet er als volgt uit:

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

    • opties

      voorwerp

      • evenement

        UitbreidbaarEvent

        De gebeurtenis die het verzoek heeft geactiveerd.

      • verzoek

        Verzoek

        Het verzoek om te behandelen.

    • retourneert

      Beloof<Reactie>

      Er wordt een belofte teruggegeven als een geregistreerde route het verzoek kan verwerken. Als er geen overeenkomende route is en er geen defaultHandler is, wordt undefined geretourneerd.

  • registreerRoute

    leegte

    Registreert een route bij de router.

    De registerRoute functie ziet er als volgt uit:

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

    • route

      De route om te registreren.

  • setCatchHandler

    leegte

    Als een route een fout genereert tijdens het afhandelen van een verzoek, wordt deze handler aangeroepen en krijgt hij de kans om een ​​antwoord te geven.

    De setCatchHandler -functie ziet er als volgt uit:

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

    • begeleider

      Een callback-functie die een belofte retourneert, resulterend in een antwoord.

  • setDefaultHandler

    leegte

    Definieer een handler die wordt aangeroepen als er geen routes expliciet overeenkomen met de binnenkomende aanvraag.

    Elke HTTP-methode ('GET', 'POST', enz.) krijgt zijn eigen standaardhandler.

    Zonder een standaardhandler zullen niet-gematchte verzoeken tegen het netwerk ingaan alsof er geen servicemedewerker aanwezig is.

    De setDefaultHandler -functie ziet er als volgt uit:

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

    • begeleider

      Een callback-functie die een belofte retourneert, resulterend in een antwoord.

    • methode

      HTTPMethode optioneel

  • route afmelden

    leegte

    Maakt de registratie van een route bij de router ongedaan.

    De unregisterRoute functie ziet er als volgt uit:

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

    • route

      De route om u af te melden.

Methoden

registerRoute()

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

Registreer eenvoudig een RegExp, string of functie met een cachingstrategie op een Singleton Router-instantie.

Deze methode genereert indien nodig een route voor u en roept workbox-routing.Router#registerRoute aan.

Parameters

  • vastlegging

    tekenreeks | RegExp | RouteMatchCallback | Route

    Als de capture-parameter Route is, worden alle andere argumenten genegeerd.

  • begeleider

    RouteHandler optioneel

  • methode

    HTTPMethode optioneel

Retouren

  • De gegenereerde Route .

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

Als een route een fout genereert tijdens het afhandelen van een verzoek, wordt deze handler aangeroepen en krijgt hij de kans om een ​​antwoord te geven.

Parameters

  • begeleider

    Een callback-functie die een belofte retourneert, resulterend in een antwoord.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

Definieer een handler die wordt aangeroepen als er geen routes expliciet overeenkomen met de binnenkomende aanvraag.

Zonder een standaardhandler zullen niet-gematchte verzoeken tegen het netwerk ingaan alsof er geen servicemedewerker aanwezig is.

Parameters

  • begeleider

    Een callback-functie die een belofte retourneert, resulterend in een antwoord.