Un service worker puede interceptar solicitudes de red de una página. Puede responder a el navegador con contenido almacenado en caché, contenido de la red o contenido generado en el service worker.
workbox-routing
es un módulo que facilita "enrutar" estas solicitudes a
diferentes funciones que ofrecen respuestas.
Cómo se realiza el enrutamiento
Cuando una solicitud de red genera un evento de recuperación de service worker, workbox-routing
intentará responder a la solicitud con las rutas y los controladores proporcionados.
Estos son los aspectos principales que debes tener en cuenta a partir de la información anterior:
El método de solicitud es importante. De forma predeterminada, las rutas se registran
GET
solicitudes. Si quieres interceptar otros tipos de solicitudes, necesitarás para especificar el método.El orden del registro de rutas es importante. Si hay varias Rutas que puede manejar una solicitud, la ruta que se registra primero se usará para responder a la solicitud.
Existen varias formas de registrar una ruta: puedes usar devoluciones de llamada, llamadas regulares con expresiones regulares o instancias de Route.
Coincidencias y manejo en las rutas
Una "ruta" en la caja de trabajo no son más que dos funciones: una operación de “coincidencias” función para determinar si la ruta debe coincidir con una solicitud y un “control” la función, que debe manejar la solicitud y responder con una respuesta.
Workbox incluye algunos asistentes que realizan la coincidencia y el manejo de pero si alguna vez deseas tener un comportamiento diferente, escribir un la coincidencia personalizada y la función de controlador es la mejor opción.
R
función de devolución de llamada coincidente
se le pasa un
ExtendableEvent
:
Request
y un
URL
objeto que puedes
de coincidencia mostrando un valor verdadero. Para un ejemplo sencillo, podrías comparar
una URL específica, como esta:
const matchCb = ({url, request, event}) => {
return url.pathname === '/special/url';
};
La mayoría de los casos de uso se pueden cubrir examinando o probando url
o
request
R
función de devolución de llamada del controlador
recibirán la misma
ExtendableEvent
:
Request
y
URL
objeto junto con
un valor params
, que es el valor que devuelve el comando "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,
});
};
El controlador debe mostrar una promesa que se resuelva en Response
. En este
ejemplo, usamos
async
y await
.
De forma interna, el valor de Response
que se muestra se unirá en una promesa.
Puedes registrar estas devoluciones de llamada de la siguiente manera:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
La única limitación es que la columna "match" la devolución de llamada debería de forma síncrona mostrar un mensaje verdadero
no puedes realizar ningún trabajo asíncrono. Esto se debe a que
Router
debe responder de forma síncrona al evento de recuperación o permitir que
a otros eventos de recuperación.
Normalmente, el "controlador" la devolución de llamada usará una de las estrategias proporcionadas mediante workbox-strategies, como se muestra aquí:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
En esta página, nos centraremos en workbox-routing
, pero puedes
Obtén más información sobre estas estrategias en las cajas de trabajo.
Cómo registrar una ruta de expresiones regulares
Una práctica común es usar una expresión regular en lugar de una “coincidencia” devolución de llamada. Workbox hace que esto sea fácil de implementar de la siguiente manera:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
Para las solicitudes del mismo origen, esta expresión regular coincidirá, siempre y cuando la URL de la solicitud coincida expresión regular.
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
Sin embargo, para las solicitudes de origen cruzado, las expresiones regulares
debe coincidir con el comienzo de la URL. Esto se debe a que
poco probable que con una expresión regular new RegExp('/styles/.*\\.css')
buscaste hacer coincidir los archivos CSS de terceros.
- 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 deseas este comportamiento, solo debes asegurarte de que la frecuencia
coincide con el principio de la URL. Si quisiéramos hacer coincidir el
solicitudes para https://cdn.third-party-site.com
, podríamos usar el
la expresión 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 deseas buscar coincidencias, tanto locales como de terceros, puedes usar un comodín al comienzo de la expresión regular, pero debes hacerlo con precaución para asegurarte de que no cause comportamientos inesperados en tu aplicación web.
Cómo registrar una ruta de navegación
Si tu sitio tiene una aplicación de una sola página, puedes utilizar una
NavigationRoute
a
devolver una respuesta específica para todos
de navegación.
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);
Cada vez que un usuario visite tu sitio en el navegador, se generará la solicitud de la página
Debe ser una solicitud de navegación y se entregará la página almacenada en caché /app-shell.html
.
(Nota: La página debe estar almacenada en caché a través de workbox-precaching
o mediante tu
tu propio paso de instalación).
De forma predeterminada, esto responderá a todas las solicitudes de navegación. Si deseas
restringirlo para que responda a un subconjunto de URLs, puedes usar el allowlist
y denylist
opciones para restringir qué páginas coincidirán con esta ruta.
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);
Lo único que debes tener en cuenta es que denylist
ganará si una URL está en ambos
allowlist
y denylist
.
Configura un controlador predeterminado
Si quieres proporcionar un "controlador" para solicitudes que no coinciden con una ruta, puede establecer un controlador predeterminado.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
// ...
});
Configura un controlador de captura
En caso de que alguna de tus rutas arroje un error, puedes capturar y se degradan de forma elegante mediante la configuración de un controlador catch.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
...
});
Cómo definir una ruta para solicitudes que no son GET
De forma predeterminada, se supone que todas las rutas corresponden a solicitudes GET
.
Si quieres enrutar otras solicitudes, como una POST
, necesitas
para definir el método al registrar la ruta, de la siguiente manera:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
Registro del router
Deberías poder determinar el flujo de una solicitud con los registros de
workbox-routing
, que destacará las URLs que se están procesando
a través de Workbox.
Si necesitas información más detallada, puedes establecer el nivel de registro en debug
para
Ver registros en solicitudes que no maneja el router. Consulta nuestra
guía de depuración para obtener más información
configurar el nivel de registro.
Uso avanzado
Si quieres tener más control sobre cuándo se proporciona el router de la caja de trabajo
solicitudes, puedes crear tu propia
Instancia Router
y llamada
Es handleRequest()
cada vez que quieras usar el router para responder a una solicitud.
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.
}
});
Cuando uses Router
directamente, también deberás usar la clase Route
,
o cualquiera de las clases extendidas
para registrar rutas.
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));
Tipos
NavigationRoute
NavigationRoute facilita la creación de un
workbox-routing.Route
que coincide con el navegador
[solicitudes de navegación]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests
.
Solo coincidirá con las solicitudes entrantes que
https://fetch.spec.whatwg.org/#concept-request-mode|mode
se estableció en navigate
.
De manera opcional, solo puedes aplicar esta ruta a un subconjunto de solicitudes de navegación
Mediante uno o ambos parámetros denylist
y allowlist
.
Propiedades
-
void
Si se proporcionan
denylist
yallowlist
,denylist
tendrá prioridad y la solicitud no coincidirá con esta ruta.Las expresiones regulares en
allowlist
ydenylist
se comparan con los atributos [pathname
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname
y [search
]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search
partes de la URL solicitada.Nota: Estas regex pueden evaluarse en función de cada URL de destino durante la navegación. Evita el uso RegExps complejos, De lo contrario, es posible que los usuarios experimenten demoras cuando naveguen por tu sitio.
La función
constructor
se ve de la siguiente manera:(handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...}
-
Una devolución de llamada que devuelve una promesa, que da como resultado una respuesta.
-
NavigationRouteMatchOptions opcional
-
-
RouteHandlerObject opcional
-
HTTPMethod
-
void
La función
setCatchHandler
se ve de la siguiente manera:(handler: RouteHandler) => {...}
-
Una devolución de llamada función que devuelve una promesa que da como resultado una respuesta
-
NavigationRouteMatchOptions
Propiedades
-
ExpExp[] opcional
-
ExpExp[] opcional
RegExpRoute
RegExpRoute facilita la creación de una expresión regular basada
workbox-routing.Route
En el caso de las solicitudes del mismo origen, la regex solo debe coincidir con una parte de la URL. Para solicitudes contra servidores de terceros, debes definir una regex que coincida el inicio de la URL.
Propiedades
-
constructor
void
Si la expresión regular contiene [grupos de captura]
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references
, los valores capturados se pasan alparams
deworkbox-routing~handlerCallback
argumento.La función
constructor
se ve de la siguiente manera:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...}
-
regExp
RegExp
La expresión regular que debe coincidir con las URLs.
-
handler
Una devolución de llamada que devuelve una promesa, que da como resultado una respuesta.
-
method
HTTPMethod opcional
-
muestra
-
-
catchHandler
RouteHandlerObject opcional
-
handler
-
coincidencia
-
method
HTTPMethod
-
setCatchHandler
void
La función
setCatchHandler
se ve de la siguiente manera:(handler: RouteHandler) => {...}
-
handler
Una devolución de llamada función que devuelve una promesa que da como resultado una respuesta
-
Route
Un Route
consiste en un par de funciones de devolución de llamada "match" y "handler".
La coincidencia la devolución de llamada determina si una ruta se debe usar para "manejar" pañal
solicitud mostrando un valor no falso, si es posible. El "controlador" devolución de llamada
Se llama cuando hay una coincidencia y se debe mostrar una promesa que resuelva el problema.
a un Response
.
Propiedades
-
constructor
void
Constructor de la clase Route.
La función
constructor
se ve de la siguiente manera:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...}
-
coincidencia
Una función de devolución de llamada que determina si la ruta coincide con un determinado
fetch
si muestra un valor no falso. -
handler
Una devolución de llamada función que devuelve una promesa que da como resultado una respuesta.
-
method
HTTPMethod opcional
-
muestra
-
-
catchHandler
RouteHandlerObject opcional
-
handler
-
coincidencia
-
method
HTTPMethod
-
setCatchHandler
void
La función
setCatchHandler
se ve de la siguiente manera:(handler: RouteHandler) => {...}
-
handler
Una devolución de llamada función que devuelve una promesa que da como resultado una respuesta
-
Router
Se puede usar el router para procesar un FetchEvent
con uno o más
workbox-routing.Route
, y se responde con un Response
si
existe una ruta coincidente.
Si ninguna ruta coincide con una solicitud determinada, el router usará una conexión si hay uno definido.
Si la ruta coincidente arroja un error, el router usará una sentencia “catch”. si uno está definido para tratar los problemas correctamente y responder con un Solicitud.
Si una solicitud coincide con varias rutas, la ruta registrada más antigua usarse para responder a la solicitud.
Propiedades
-
constructor
void
Inicializa un router nuevo.
La función
constructor
se ve de la siguiente manera:() => {...}
-
muestra
-
-
rutas
Map<HTTPMethodRoute[]>
-
addCacheListener
void
Agrega un objeto de escucha de eventos de mensaje para que las URLs se almacenen en caché desde la ventana. Esto es útil para almacenar en caché los recursos cargados en la página antes del momento en que el service worker empezó a controlarlo.
El formato de los datos del mensaje que se envían desde la ventana debe ser el siguiente. En el que el array
urlsToCache
puede constar de cadenas de URL o un array de String de URL + objetorequestInit
(la misma que pasarías afetch()
){ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }
La función
addCacheListener
se ve de la siguiente manera:() => {...}
-
addFetchListener
void
Agrega un objeto de escucha de eventos de recuperación para responder a eventos cuando coincide una ruta. la solicitud del evento.
La función
addFetchListener
se ve de la siguiente manera:() => {...}
-
findMatchingRoute
void
Compara una solicitud y una URL (y opcionalmente un evento) con la lista de rutas registradas y, si hay una coincidencia, devuelve el resultado junto con cualquier parámetro que genere la coincidencia.
La función
findMatchingRoute
se ve de la siguiente manera:(options: RouteMatchCallbackOptions) => {...}
-
opciones
-
muestra
objeto
Un objeto con propiedades
route
yparams
Se propagan si se encuentra una ruta coincidente oundefined
de lo contrario.
-
-
handleRequest
void
Aplicar las reglas de enrutamiento a un objeto FetchEvent para obtener una respuesta de un al controlador de rutas adecuado.
La función
handleRequest
se ve de la siguiente manera:(options: object) => {...}
-
opciones
objeto
-
evento
ExtendableEvent
El evento que activó el para cada solicitud.
-
request
Solicitud
La solicitud que se debe controlar.
-
-
muestra
Promise<Response>
Se devuelve una promesa si un la ruta registrada puede manejar la solicitud. Si no hay coincidencias ruta y no hay
defaultHandler
, se devuelveundefined
.
-
-
registerRoute
void
Registra una ruta con el router.
La función
registerRoute
se ve de la siguiente manera:(route: Route) => {...}
-
ruta
La ruta que se registrará.
-
-
setCatchHandler
void
Si una ruta arroja un error mientras se procesa una solicitud, esta
handler
se llamará y tendrá la oportunidad de proporcionar una respuesta.La función
setCatchHandler
se ve de la siguiente manera:(handler: RouteHandler) => {...}
-
handler
Una devolución de llamada que devuelve una promesa, que da como resultado una respuesta.
-
-
setDefaultHandler
void
Define un
handler
predeterminado que se llame cuando no hay rutas de forma explícita. coincide con la solicitud entrante.Cada método HTTP ("GET", "POST", etc.) obtiene su propio controlador predeterminado.
Sin un controlador predeterminado, las solicitudes no coincidentes irán en contra del red como si no hubiera un service worker presente.
La función
setDefaultHandler
se ve de la siguiente manera:(handler: RouteHandler, method?: HTTPMethod) => {...}
-
handler
Una devolución de llamada que devuelve una promesa, que da como resultado una respuesta.
-
method
HTTPMethod opcional
-
-
unregisterRoute
void
Cancela el registro de una ruta con el router.
La función
unregisterRoute
se ve de la siguiente manera:(route: Route) => {...}
-
ruta
La ruta para cancelar el registro.
-
Métodos
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
)
Registra fácilmente una regex, una cadena o una función con un almacenamiento en caché estrategia a una instancia de un router singleton.
Este método generará una Ruta para ti si es necesario y
llama a workbox-routing.Router#registerRoute
.
Parámetros
-
capturar
string | Exp. | RouteMatchCallback | Ruta
Si el parámetro de captura es
Route
, se ignorarán todos los demás argumentos. -
handler
RouteHandler opcional
-
method
HTTPMethod opcional
Muestra
-
El
Route
generado.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
)
Si una ruta arroja un error mientras se procesa una solicitud, esta handler
se llamará y tendrá la oportunidad de proporcionar una respuesta.
Parámetros
-
handler
Una devolución de llamada que devuelve una promesa, que da como resultado una respuesta.
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
)
Define un handler
predeterminado que se llame cuando no hay rutas de forma explícita.
coincide con la solicitud entrante.
Sin un controlador predeterminado, las solicitudes no coincidentes irán en contra del red como si no hubiera un service worker presente.
Parámetros
-
handler
Una devolución de llamada que devuelve una promesa, que da como resultado una respuesta.