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.
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.
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.
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
-
void
Si les champs
denylist
etallowlist
sont tous les deux fournis, le champdenylist
est prioritaire, et la requête ne correspond pas à cette route.Les expressions régulières dans
allowlist
etdenylist
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) => {...}
-
Fonction de rappel qui renvoie une promesse entraînant une réponse.
-
NavigationRouteMatchOptions facultatif
-
-
RouteHandlerObject facultatif
-
HTTPMethod
-
void
La fonction
setCatchHandler
se présente comme suit :(handler: RouteHandler) => {...}
-
Fonction de rappel qui renvoie une promesse résolue en réponse à une réponse
-
NavigationRouteMatchOptions
Propriétés
-
RegExp[] facultatif
-
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'argumentparams
deworkbox-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
-
retours
-
-
catchHandler
RouteHandlerObject facultatif
-
handler
-
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
-
retours
-
-
catchHandler
RouteHandlerObject facultatif
-
handler
-
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 :() => {...}
-
retours
-
-
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 objetrequestInit
(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) => {...}
-
options
-
retours
objet
Un objet avec les propriétés
route
etparams
. Ils sont renseignés si une route correspondante a été trouvée, ouundefined
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.