routage de la boîte de travail

Un service worker peut intercepter des requêtes réseau pour une page. Il peut répondre au navigateur avec du contenu mis en cache, du contenu du réseau ou du contenu généré dans le service worker.

workbox-routing est un module qui permet d'acheminer facilement ces requêtes vers différentes fonctions fournissant des réponses.

Fonctionnement du routage

Lorsqu'une requête réseau provoque un événement de récupération par un service worker, workbox-routing tente de répondre à la requête à l'aide des routes et des gestionnaires fournis.

Schéma de routage de la boîte de travail

Voici les principaux points à prendre en compte:

  • La méthode de requête est importante. Par défaut, les routes sont enregistrées pour les requêtes GET. Si vous souhaitez intercepter d'autres types de requêtes, vous devez spécifier la méthode.

  • L'ordre d'enregistrement des itinéraires est important. Si plusieurs routes sont enregistrées et capables de gérer une requête, la route enregistrée en premier est utilisée pour répondre à la requête.

Il existe plusieurs façons d'enregistrer une route: vous pouvez utiliser des rappels, des expressions régulières ou des instances de route.

Mise en correspondance et gestion des routes

Une "route" dans la boîte de travail n'a rien de plus que deux fonctions: une fonction de "correspondance" pour déterminer si l'itinéraire doit correspondre à une requête, et une fonction de "traitement", qui doit gérer la requête et répondre avec une réponse.

Workbox est fourni avec des assistants qui effectuent la mise en correspondance et la gestion à votre place. Toutefois, si vous souhaitez un comportement différent, l'écriture d'une fonction de correspondance et de gestionnaire personnalisée est la meilleure option.

Une fonction de rappel de correspondance reçoit un ExtendableEvent, un Request et un objet URL que vous pouvez mettre en correspondance en renvoyant une valeur fiable. Voici un exemple simple de mise en correspondance avec une URL spécifique:

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

La plupart des cas d'utilisation peuvent être couverts par l'examen / test de url ou de request.

Une fonction de rappel de gestionnaire reçoit les mêmes ExtendableEvent, Request et URL objet, ainsi qu'une valeur params, qui est la valeur renvoyée par la fonction "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,
  });
};

Votre gestionnaire doit renvoyer une promesse qui se résout en Response. Dans cet exemple, nous utilisons async et await. En arrière-plan, la valeur Response renvoyée est encapsulée dans une promesse.

Vous pouvez enregistrer ces rappels comme suit:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb);

La seule limite est que le rappel de "correspondance" doit de manière synchrone renvoyer une valeur fiable. Vous ne pouvez effectuer aucune tâche asynchrone. En effet, Router doit répondre de manière synchrone à l'événement d'extraction ou permettre de basculer vers d'autres événements de récupération.

Normalement, le rappel "handler" doit utiliser l'une des stratégies fournies par les stratégies de boîte de travail, comme suit:

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

registerRoute(matchCb, new StaleWhileRevalidate());

Sur cette page, nous nous concentrerons sur workbox-routing, mais vous pouvez en savoir plus sur ces stratégies sur les stratégies de boîte de travail.

Enregistrer une route d'expression régulière

Une pratique courante consiste à utiliser une expression régulière au lieu d'un rappel de "correspondance". Workbox facilite l'implémentation de cette solution, comme suit:

import {registerRoute} from 'workbox-routing';

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

Pour les requêtes ayant la même origine, cette expression régulière correspondra tant que l'URL de la requête correspond à l'expression régulière.

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

Toutefois, pour les requêtes multi-origines, les expressions régulières doivent correspondre au début de l'URL. En effet, il est peu probable qu'avec une expression régulière new RegExp('/styles/.*\\.css'), vous vouliez mettre en correspondance des fichiers CSS tiers.

  • 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

Si vous vouliez ce comportement, il vous suffit de vous assurer que l'expression régulière correspond au début de l'URL. Pour faire correspondre les requêtes pour https://cdn.third-party-site.com, nous pouvons utiliser l'expression régulière 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

Si vous souhaitez établir une correspondance avec des tiers locaux et tiers, vous pouvez utiliser un caractère générique au début de votre expression régulière. Toutefois, faites-le avec précaution afin d'éviter tout comportement inattendu dans votre application Web.

Comment enregistrer un itinéraire de navigation

Si votre site est une application monopage, vous pouvez utiliser un élément NavigationRoute pour renvoyer une réponse spécifique à toutes les requêtes de navigation.

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

Chaque fois qu'un utilisateur accède à votre site dans le navigateur, la requête concernant cette page est une requête de navigation, et la page mise en cache /app-shell.html est diffusée. (Remarque: la page doit être mise en cache via workbox-precaching ou via votre propre étape d'installation.)

Par défaut, il répond à toutes les requêtes de navigation. Si vous souhaitez restreindre la réponse à un sous-ensemble d'URL, vous pouvez utiliser les options allowlist et denylist pour limiter les pages qui correspondent à cet itinéraire.

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

La seule chose à noter est que l'élément denylist l'emportera si une URL se trouve à la fois dans allowlist et dans denylist.

Définir un gestionnaire par défaut

Si vous souhaitez fournir un "gestionnaire" pour les requêtes qui ne correspondent pas à une route, vous pouvez définir un gestionnaire par défaut.

import {setDefaultHandler} from 'workbox-routing';

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

Définir un gestionnaire d'interceptions

Dans le cas où l'une de vos routes génère une erreur, vous pouvez effectuer une capture et une dégradation élégante en définissant un gestionnaire "catch".

import {setCatchHandler} from 'workbox-routing';

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

Définir une route pour les requêtes non-GET

Par défaut, toutes les routes sont considérées comme correspondant aux requêtes GET.

Si vous souhaitez acheminer d'autres requêtes, comme une requête POST, vous devez définir la méthode lors de l'enregistrement de la route, comme suit:

import {registerRoute} from 'workbox-routing';

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

Journalisation du routeur

Vous devriez pouvoir déterminer le flux d'une requête à l'aide des journaux de workbox-routing, qui mettent en évidence les URL traitées via Workbox.

Journaux de routage

Si vous avez besoin d'informations plus détaillées, vous pouvez définir le niveau de journalisation sur debug pour afficher les journaux des requêtes non traitées par le routeur. Pour en savoir plus sur la définition du niveau de journalisation, consultez notre guide de débogage.

Messages de débogage et de routage des journaux

Utilisation avancée

Si vous souhaitez mieux contrôler le moment où le routeur de boîte de travail reçoit les requêtes, vous pouvez créer votre propre instance Router et appeler sa méthode handleRequest() chaque fois que vous souhaitez utiliser le routeur pour répondre à une requête.

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

Lorsque vous utilisez directement Router, vous devez également utiliser la classe Route ou l'une des classes d'extension pour enregistrer des routes.

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

Types

NavigationRoute

NavigationRoute permet de créer facilement un workbox-routing.Route correspondant aux [requêtes de navigation]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests du navigateur.

Il ne met en correspondance que les requêtes entrantes dont la propriété https://fetch.spec.whatwg.org/#concept-request-mode|mode est définie sur navigate.

Vous pouvez éventuellement n'appliquer cet itinéraire qu'à un sous-ensemble de requêtes de navigation en utilisant l'un des paramètres denylist et allowlist, ou les deux.

Propriétés

  • constructor

    void

    Si les champs denylist et allowlist sont tous les deux fournis, le champ denylist est prioritaire, et la requête ne correspond pas à cette route.

    Les expressions régulières dans allowlist et denylist sont mises en correspondance avec les parties [pathname]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname et [search]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search concaténées de l'URL demandée.

    Remarque: Ces expressions régulières peuvent être évaluées par rapport à chaque URL de destination lors d'une navigation. Évitez d'utiliser des expressions régulières complexes, sinon vos utilisateurs risquent de constater du retard lorsqu'ils naviguent sur votre site.

    La fonction constructor se présente comme suit :

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

  • catchHandler

    RouteHandlerObject facultatif

  • correspondance
  • method

    HTTPMethod

  • setCatchHandler

    void

    La fonction setCatchHandler se présente comme suit :

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

    • handler

      Fonction de rappel qui renvoie une promesse résolue en réponse à une réponse

NavigationRouteMatchOptions

Propriétés

  • liste d'autorisation

    RegExp[] facultatif

  • liste de blocage

    RegExp[] facultatif

RegExpRoute

RegExpRoute permet de créer facilement une expression régulière basée sur workbox-routing.Route.

Pour les requêtes de même origine, l'expression régulière ne doit correspondre qu'à une partie de l'URL. Pour les requêtes adressées à des serveurs tiers, vous devez définir une expression régulière qui correspond au début de l'URL.

Propriétés

  • constructor

    void

    Si l'expression régulière contient [groupes de capture]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references, les valeurs capturées sont transmises à l'argument params de workbox-routing~handlerCallback.

    La fonction constructor se présente comme suit :

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

    • regExp

      RegExp

      Expression régulière à mettre en correspondance avec les URL.

    • handler

      Fonction de rappel qui renvoie une promesse entraînant une réponse.

    • method

      HTTPMethod facultatif

  • catchHandler

    RouteHandlerObject facultatif

  • correspondance
  • method

    HTTPMethod

  • setCatchHandler

    void

    La fonction setCatchHandler se présente comme suit :

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

    • handler

      Fonction de rappel qui renvoie une promesse résolue en réponse à une réponse

Route

Un Route se compose d'une paire de fonctions de rappel, "match" et "handler". Le rappel "match" détermine si une route doit être utilisée pour "gérer" une requête en renvoyant, si possible, une valeur non fausse. Le rappel "handler" est appelé en cas de correspondance et doit renvoyer une promesse qui se résout en Response.

Propriétés

  • constructor

    void

    Constructeur pour la classe Route.

    La fonction constructor se présente comme suit :

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

    • correspondance

      Fonction de rappel qui détermine si l'itinéraire correspond à un événement fetch donné en renvoyant une valeur non erronée.

    • handler

      Fonction de rappel qui renvoie une promesse résolue en réponse.

    • method

      HTTPMethod facultatif

  • catchHandler

    RouteHandlerObject facultatif

  • correspondance
  • method

    HTTPMethod

  • setCatchHandler

    void

    La fonction setCatchHandler se présente comme suit :

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

    • handler

      Fonction de rappel qui renvoie une promesse résolue en réponse à une réponse

Router

Le routeur peut être utilisé pour traiter une FetchEvent à l'aide d'un ou de plusieurs workbox-routing.Route, en répondant avec un Response si une route correspondante existe.

Si aucune route ne correspond à une requête donnée, le routeur utilise un gestionnaire "par défaut" s'il est défini.

Si la route correspondante génère une erreur, le routeur utilise un gestionnaire "catch" s'il est défini pour gérer correctement les problèmes et répondre avec une requête.

Si une requête correspond à plusieurs routes, la route enregistrée la plus ancienne sera utilisée pour y répondre.

Propriétés

  • constructor

    void

    Initialise un nouveau routeur.

    La fonction constructor se présente comme suit :

    ()=> {...}

  • routes

    Map<HTTPMethodRoute[]>

  • addCacheListener

    void

    Ajoute un écouteur d'événements de message pour les URL à mettre en cache depuis la fenêtre. Cela est utile pour mettre en cache les ressources chargées sur la page avant le moment où le service worker a commencé à la contrôler.

    Le format des données de message envoyées depuis la fenêtre doit se présenter comme suit. Où le tableau urlsToCache peut être constitué de chaînes d'URL ou d'un tableau de chaîne d'URL + un objet requestInit (identique à transmettre à fetch()).

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

    La fonction addCacheListener se présente comme suit :

    ()=> {...}

  • addFetchListener

    void

    Ajoute un écouteur d'événements de récupération pour répondre aux événements lorsqu'une route correspond à la requête de l'événement.

    La fonction addFetchListener se présente comme suit :

    ()=> {...}

  • findMatchingRoute

    void

    Vérifie une requête et une URL (et éventuellement un événement) par rapport à la liste des itinéraires enregistrés. En cas de correspondance, il renvoie la route correspondante, ainsi que tous les paramètres générés par la correspondance.

    La fonction findMatchingRoute se présente comme suit :

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

    • retours

      objet

      Un objet avec les propriétés route et params. Ils sont renseignés si une route correspondante a été trouvée, ou undefined dans le cas contraire.

  • handleRequest

    void

    Appliquez les règles de routage à un objet FetchEvent pour obtenir une réponse d'un gestionnaire de route approprié.

    La fonction handleRequest se présente comme suit :

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

    • options

      objet

      • event

        ExtendableEvent

        Événement ayant déclenché la requête.

      • request

        Requête

        Requête à traiter.

    • retours

      Promesse<Réponse>

      Une promesse est renvoyée si une route enregistrée peut gérer la requête. En l'absence de route correspondante et de defaultHandler, undefined est renvoyé.

  • registerRoute

    void

    Enregistre une route auprès du routeur.

    La fonction registerRoute se présente comme suit :

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

    • itinéraire

      Route à enregistrer.

  • setCatchHandler

    void

    Si une route génère une erreur lors du traitement d'une requête, ce handler est appelé et a la possibilité de fournir une réponse.

    La fonction setCatchHandler se présente comme suit :

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

    • handler

      Fonction de rappel qui renvoie une promesse entraînant une réponse.

  • setDefaultHandler

    void

    Définissez un handler par défaut qui est appelé lorsqu'aucune route ne correspond explicitement à la requête entrante.

    Chaque méthode HTTP ('GET', 'POST', etc.) dispose de son propre gestionnaire par défaut.

    Sans gestionnaire par défaut, les requêtes sans correspondance sont envoyées au réseau comme si aucun service worker n'était présent.

    La fonction setDefaultHandler se présente comme suit :

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

    • handler

      Fonction de rappel qui renvoie une promesse entraînant une réponse.

    • method

      HTTPMethod facultatif

  • unregisterRoute

    void

    Annule l'enregistrement d'une route auprès du routeur.

    La fonction unregisterRoute se présente comme suit :

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

    • itinéraire

      Route pour laquelle l'enregistrement doit être annulé.

Méthodes

registerRoute()

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

Enregistrez facilement une expression régulière, une chaîne ou une fonction avec une stratégie de mise en cache sur une instance de routeur singleton.

Cette méthode génère une route si nécessaire et appelle workbox-routing.Router#registerRoute.

Paramètres

  • capture

    chaîne|RegExp|RouteMatchCallback|Route

    Si le paramètre de capture est une Route, tous les autres arguments sont ignorés.

  • handler

    RouteHandler facultatif

  • method

    HTTPMethod facultatif

Renvoie

  • Le Route généré.

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

Si une route génère une erreur lors du traitement d'une requête, ce handler est appelé et a la possibilité de fournir une réponse.

Paramètres

  • handler

    Fonction de rappel qui renvoie une promesse entraînant une réponse.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

Définissez un handler par défaut qui est appelé lorsqu'aucune route ne correspond explicitement à la requête entrante.

Sans gestionnaire par défaut, les requêtes sans correspondance sont envoyées au réseau comme si aucun service worker n'était présent.

Paramètres

  • handler

    Fonction de rappel qui renvoie une promesse entraînant une réponse.