Un service worker può intercettare le richieste di rete per una pagina. Potrebbe rispondere al browser con contenuti memorizzati nella cache, contenuti della rete o contenuti generati dal service worker.
workbox-routing
è un modulo che semplifica il routing di queste richieste a diverse funzioni che forniscono risposte.
Modalità di esecuzione dei percorsi
Quando una richiesta di rete causa un evento di recupero del service worker, workbox-routing
proverà a rispondere alla richiesta utilizzando le route e i gestori specificati.
Gli elementi principali da notare quanto sopra sono:
Il metodo di una richiesta è importante. Per impostazione predefinita, le route sono registrate per le richieste
GET
. Se vuoi intercettare altri tipi di richieste, devi specificare il metodo.L'ordine di registrazione della route è importante. Se vengono registrate più route che potrebbero gestire una richiesta, verrà utilizzata per prima la route registrata per prima.
Esistono alcuni modi per registrare una route: puoi utilizzare callback, espressioni regolari o istanze di route.
Corrispondenza e gestione nelle route
Una "route" nella casella di lavoro non è altro che due funzioni: una funzione di "corrispondenza" per determinare se la route deve corrispondere a una richiesta e una funzione di "elaborazione", che deve gestire la richiesta e rispondere con una risposta.
Workbox viene fornito con alcuni assistenti che si occuperanno di corrispondenza e gestione, ma se ti capitasse di volere comportamenti diversi, scrivere una funzione di corrispondenza e gestore personalizzata è l'opzione migliore.
A una
funzione di callback di corrispondenza
vengono trasmessi un
ExtendableEvent
,
Request
e un
oggettoURL
che puoi trovare
restituendo un valore attendibile. Come semplice esempio, potresti associare
un URL specifico, ad esempio:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
La maggior parte dei casi d'uso può essere esaminata / testando url
o request
.
A una funzione di callback del gestore verranno assegnati lo stesso ExtendableEvent
, Request
e URL
oggetto insieme a un valore params
, che è il valore restituito dalla funzione "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,
});
};
Il tuo gestore deve restituire una promessa che si risolve in un Response
. In questo
esempio utilizziamo
async
e await
.
In dettaglio, il valore restituito Response
sarà racchiuso in una promessa.
Puoi registrare questi callback nel seguente modo:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
L'unica limitazione è che il callback"match" deve restituire in modo sincrono un valore attendibile, quindi non puoi eseguire alcuna operazione asincrona. Il motivo è che Router
deve rispondere in modo sincrono all'evento di recupero o consentire di passare ad altri eventi di recupero.
Normalmente il callback "handler" utilizza una delle strategie fornite dalle workbox-strategie, ad esempio:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
In questa pagina ci concentreremo su workbox-routing
, ma puoi
scoprire di più su queste strategie relative alle strategie-box di lavoro.
Come registrare un percorso di espressione regolare
Una pratica comune consiste nell'utilizzare un'espressione regolare invece di un callback "match". Workbox semplifica l'implementazione in questo modo:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
Per le richieste provenienti dalla stessa origine, questa espressione regolare corrisponderà purché l'URL della richiesta corrisponda all'espressione regolare.
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
Tuttavia, per le richieste multiorigine, le espressioni regolari devono corrispondere all'inizio dell'URL. Il motivo è che è
improbabile che con un'espressione regolare new RegExp('/styles/.*\\.css')
volevi trovare corrispondenze con i file CSS di terze parti.
- 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
Se vuoi questo comportamento, devi solo assicurarti che l'espressione regolare corrisponda all'inizio dell'URL. Se volessimo trovare una corrispondenza per le richieste per https://cdn.third-party-site.com
, potremmo utilizzare l'espressione regolare 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
Se vuoi trovare corrispondenze sia con parti locali che di terze parti, puoi utilizzare un carattere jolly all'inizio dell'espressione regolare, ma devi farlo con cautela per assicurarti che non causi comportamenti imprevisti nell'app web.
Come registrare un percorso di navigazione
Se il tuo sito è un'app a pagina singola, puoi utilizzare un elemento NavigationRoute
per restituire una risposta specifica per tutte le richieste di navigazione.
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);
Ogni volta che un utente accede al tuo sito nel browser, la richiesta della pagina sarà
una richiesta di navigazione e verrà pubblicata la pagina memorizzata nella cache /app-shell.html
.
Nota: la pagina deve essere memorizzata nella cache tramite workbox-precaching
o tramite il tuo
passaggio di installazione.
Per impostazione predefinita, rispondi a tutte le richieste di navigazione. Se vuoi limitare la risposta a un sottoinsieme di URL, puoi utilizzare le opzioni allowlist
e denylist
per limitare le pagine che corrispondono a questa route.
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);
L'unica cosa da notare è che denylist
vincerà se un URL si trova sia in allowlist
che in denylist
.
Imposta un gestore predefinito
Se vuoi fornire un "gestore" per le richieste che non corrispondono a una route, puoi impostare un gestore predefinito.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
Imposta un gestore di cattura
Nel caso in cui una delle tue route restituisca un errore, puoi acquisire e ridurre gli errori impostando un gestore di rilevamento.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
Definizione di una route per le richieste non Get
Per impostazione predefinita, si presume che tutte le route siano per le richieste GET
.
Se vuoi indirizzare altre richieste, ad esempio una richiesta POST
, devi definire il metodo durante la registrazione della route, in questo modo:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
Logging del router
Dovresti essere in grado di determinare il flusso di una richiesta utilizzando i log di
workbox-routing
, che evidenzieranno gli URL elaborati
tramite Workbox.
Se hai bisogno di informazioni più dettagliate, puoi impostare il livello di log su debug
per visualizzare i log delle richieste non gestite dal router. Consulta la nostra guida al debug per ulteriori informazioni sull'impostazione del livello di log.
Utilizzo avanzato
Se vuoi avere maggiore controllo su quando il router Workbox riceve le richieste, puoi creare la tua istanza Router
e chiamare il suo metodo handleRequest()
ogni volta che vuoi utilizzare il router per rispondere a una richiesta.
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.
}
});
Quando si utilizza direttamente Router
, è necessario utilizzare anche la classe Route
,
o qualsiasi classe di estensione per registrare le 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));
Tipi
NavigationRoute
NavigationRoute semplifica la creazione di un elemento workbox-routing.Route
corrispondente per le [richieste di navigazione]del browserhttps://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests
.
Corrisponderà solo alle richieste in entrata il cui
https://fetch.spec.whatwg.org/#concept-request-mode|mode
è impostato su navigate
.
Facoltativamente, puoi applicare questa route solo a un sottoinsieme di richieste di navigazione utilizzando uno o entrambi i parametri denylist
e allowlist
.
Proprietà
-
void
Se vengono forniti sia
denylist
siaallowlist
,denylist
avrà la precedenza e la richiesta non corrisponderà a questa route.Le espressioni regolari in
allowlist
edenylist
vengono confrontate con le porzioni [pathname
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname
e [search
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search
concatenate dell'URL richiesto.Nota: queste espressioni regolari possono essere valutate in base a ogni URL di destinazione durante una navigazione. Evita di utilizzare RegExp complesse, altrimenti gli utenti potrebbero riscontrare ritardi durante la navigazione sul sito.
La funzione
constructor
ha il seguente aspetto:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
Una funzione di callback che restituisce una Promessa che genera una Risposta.
-
NavigationRouteMatchOptions facoltativo
-
-
Facoltativo RouteHandlerObject
-
HTTPMethod
-
void
La funzione
setCatchHandler
ha il seguente aspetto:(handler: RouteHandler) => {...}
-
Una funzione di callback che restituisce una promessa che si risolve in una risposta
-
NavigationRouteMatchOptions
Proprietà
-
RegExp[] facoltativo
-
RegExp[] facoltativo
RegExpRoute
RegExpRoute semplifica la creazione di un'espressione regolare basata su workbox-routing.Route
.
Per le richieste della stessa origine, l'espressione regolare deve corrispondere solo a una parte dell'URL. Per le richieste contro server di terze parti, devi definire un'espressione regolare che corrisponda all'inizio dell'URL.
Proprietà
-
costruttore
void
Se l'espressione regolare contiene [gruppi di acquisizione]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
, i valori acquisiti verranno passati all'argomentoworkbox-routing~handlerCallback
params
.La funzione
constructor
ha il seguente aspetto:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
L'espressione regolare per la corrispondenza con gli URL.
-
handler
Una funzione di callback che restituisce una Promessa che genera una Risposta.
-
method
HTTPMethod facoltativo
-
returns
-
-
catchHandler
Facoltativo RouteHandlerObject
-
handler
-
corrispondenza
-
method
HTTPMethod
-
setCatchHandler
void
La funzione
setCatchHandler
ha il seguente aspetto:(handler: RouteHandler) => {...}
-
handler
Una funzione di callback che restituisce una promessa che si risolve in una risposta
-
Route
Un Route
è costituito da una coppia di funzioni di callback, "match" e "handler".
Il callback "match" determina se una route deve essere utilizzata per "gestire" una richiesta restituendo un valore non falsy, se possibile. Il callback "handler" viene chiamato quando esiste una corrispondenza e dovrebbe restituire una Promise che si risolve in Response
.
Proprietà
-
costruttore
void
Costruttore per la classe Route.
La funzione
constructor
ha il seguente aspetto:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
corrispondenza
Una funzione di callback che determina se la route corrisponde a un determinato evento
fetch
restituendo un valore non falsy. -
handler
Una funzione di callback che restituisce una promessa che si risolve in una risposta.
-
method
HTTPMethod facoltativo
-
returns
-
-
catchHandler
Facoltativo RouteHandlerObject
-
handler
-
corrispondenza
-
method
HTTPMethod
-
setCatchHandler
void
La funzione
setCatchHandler
ha il seguente aspetto:(handler: RouteHandler) => {...}
-
handler
Una funzione di callback che restituisce una promessa che si risolve in una risposta
-
Router
Il router può essere utilizzato per elaborare un FetchEvent
utilizzando uno o più
workbox-routing.Route
, rispondendo con un Response
se
esiste una route corrispondente.
Se nessuna route corrisponde a una determinata richiesta, il router utilizzerà un gestore "predefinito", se ne è stato definito uno.
Se la route corrispondente genera un errore, il router utilizzerà un gestore di "catch" se ne viene definito uno per gestire i problemi e rispondere con una richiesta.
Se una richiesta corrisponde a più route, per rispondere alla richiesta verrà utilizzata la route registrata prima.
Proprietà
-
costruttore
void
Inizializza un nuovo router.
La funzione
constructor
ha il seguente aspetto:() => {...}
-
returns
-
-
route
Map<HTTPMethodRoute[]>
-
addCacheListener
void
Aggiunge un listener di eventi di messaggi per gli URL da memorizzare nella cache dalla finestra. Questo è utile per memorizzare nella cache le risorse caricate sulla pagina prima che il service worker abbia iniziato a controllarla.
Il formato dei dati dei messaggi inviati dalla finestra deve essere il seguente. Dove l'array
urlsToCache
può essere composto da stringhe URL o un array di stringhe URL + oggettorequestInit
(lo stesso che passeresti afetch()
).{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
La funzione
addCacheListener
ha il seguente aspetto:() => {...}
-
addFetchListener
void
Aggiunge un listener di eventi di recupero per rispondere agli eventi quando una route corrisponde alla richiesta dell'evento.
La funzione
addFetchListener
ha il seguente aspetto:() => {...}
-
findMatchingRoute
void
Controlla una richiesta e un URL (e, facoltativamente, un evento) in base all'elenco delle route registrate e, in caso di corrispondenza, restituisce la route corrispondente insieme agli eventuali parametri generati dalla corrispondenza.
La funzione
findMatchingRoute
ha il seguente aspetto:(options: RouteMatchCallbackOptions) => {...}
-
opzioni del modello.
-
returns
oggetto
Un oggetto con proprietà
route
eparams
. Vengono compilate se è stata trovata una route corrispondente oundefined
altrimenti.
-
-
handleRequest
void
Applica le regole di routing a un oggetto FetchEvent per ricevere una risposta dal gestore di una route appropriata.
La funzione
handleRequest
ha il seguente aspetto:(options: object) => {...}
-
opzioni del modello.
oggetto
-
event
ExtendableEvent
L'evento che ha attivato la richiesta.
-
richiesta
Richiesta
La richiesta da gestire.
-
-
returns
Promessa<Risposta>
Se una route registrata è in grado di gestire la richiesta, viene restituita una promessa. Se non è presente alcuna route corrispondente e non è presente
defaultHandler
, viene restituitoundefined
.
-
-
registerRoute
void
Registra una route con il router.
La funzione
registerRoute
ha il seguente aspetto:(route: Route) => {...}
-
percorso
Il percorso da registrare.
-
-
setCatchHandler
void
Se una route genera un errore durante la gestione di una richiesta, questo
handler
viene chiamato e avrà la possibilità di fornire una risposta.La funzione
setCatchHandler
ha il seguente aspetto:(handler: RouteHandler) => {...}
-
handler
Una funzione di callback che restituisce una Promessa che genera una Risposta.
-
-
setDefaultHandler
void
Definisci un valore
handler
predefinito che viene richiamato quando nessuna route corrisponde esplicitamente alla richiesta in entrata.Ogni metodo HTTP ("GET", "POST" e così via) riceve il proprio gestore predefinito.
Senza un gestore predefinito, le richieste senza corrispondenza andranno sulla rete come se non fosse presente alcun service worker.
La funzione
setDefaultHandler
ha il seguente aspetto:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
handler
Una funzione di callback che restituisce una Promessa che genera una Risposta.
-
method
HTTPMethod facoltativo
-
-
unregisterRoute
void
Consente di annullare la registrazione di una route con il router.
La funzione
unregisterRoute
ha il seguente aspetto:(route: Route) => {...}
-
percorso
La route di cui annullare la registrazione.
-
Metodi
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
Registra facilmente un'espressione regolare, una stringa o una funzione con una strategia di memorizzazione nella cache su un'istanza di router singleton.
Questo metodo genererà una route per te, se necessario, e chiamerà workbox-routing.Router#registerRoute
.
Parametri
-
acquisire
stringa | RegExp | RouteMatchCallback | Route
Se il parametro di acquisizione è
Route
, tutti gli altri argomenti verranno ignorati. -
handler
RouteHandler facoltativo
-
method
HTTPMethod facoltativo
Ritorni
-
Il valore
Route
generato.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
Se una route genera un errore durante la gestione di una richiesta, questo handler
viene chiamato e avrà la possibilità di fornire una risposta.
Parametri
-
handler
Una funzione di callback che restituisce una Promessa che genera una Risposta.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
Definisci un valore handler
predefinito che viene richiamato quando nessuna route corrisponde esplicitamente
alla richiesta in entrata.
Senza un gestore predefinito, le richieste senza corrispondenza andranno sulla rete come se non fosse presente alcun service worker.
Parametri
-
handler
Una funzione di callback che restituisce una Promessa che genera una Risposta.