routing-casella di lavoro

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.

Diagramma di routing della casella di lavoro

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.

Log di routing

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.

Messaggi di debug e routing dei 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à

  • costruttore

    void

    Se vengono forniti sia denylist sia allowlist, denylist avrà la precedenza e la richiesta non corrisponderà a questa route.

    Le espressioni regolari in allowlist e denylist 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)=> {...}

  • catchHandler

    Facoltativo RouteHandlerObject

  • 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

NavigationRouteMatchOptions

Proprietà

  • lista consentita

    RegExp[] facoltativo

  • lista non consentita

    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'argomento workbox-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

  • catchHandler

    Facoltativo RouteHandlerObject

  • 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

  • catchHandler

    Facoltativo RouteHandlerObject

  • 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:

    ()=> {...}

  • 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 + oggetto requestInit (lo stesso che passeresti a fetch()).

    {
      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)=> {...}

    • returns

      oggetto

      Un oggetto con proprietà route e params. Vengono compilate se è stata trovata una route corrispondente o undefined 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

      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 restituito undefined.

  • 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.