roteamento da caixa de trabalho

Um service worker pode interceptar solicitações de rede para uma página. Ele pode responder a o navegador com conteúdo armazenado em cache, conteúdo da rede ou conteúdo gerado no service worker.

O workbox-routing é um módulo que facilita o "roteamento" essas solicitações diferentes funções que fornecem respostas.

Como o roteamento é realizado

Quando uma solicitação de rede causa um evento de busca de um service worker, workbox-routing tentará responder à solicitação usando as rotas e os manipuladores fornecidos.

Diagrama de roteamento da caixa de trabalho

Os principais pontos a serem observados acima são:

  • O método de uma solicitação é importante. Por padrão, as rotas são registradas para GET. Para interceptar outros tipos de solicitações, você vai precisar para especificar o método.

  • A ordem do registro da rota é importante. Se vários trajetos forem registrada para processar uma solicitação, a rota registrada primeiro será usado para responder à solicitação.

Há algumas maneiras de registrar uma rota: você pode usar callbacks, funções ou instâncias de rota.

Correspondência e manipulação em rotas

Uma "rota" na caixa de trabalho não é mais do que duas funções: uma "correspondência" função para determinar se a rota deve corresponder a uma solicitação e a um "processamento" função, que deve processar a solicitação e responder com uma resposta.

A caixa de trabalho vem com alguns auxiliares que realizam a correspondência e o processamento de mas, se quiser um comportamento diferente, escrever uma a função de gerenciador e correspondência personalizada é a melhor opção.

Um função de callback correspondente recebe um ExtendableEvent, Request e um URL objeto que você pode correspondentes, retornando um valor verdadeiro. Para um exemplo simples, você pode corresponder com um URL específico, como:

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

A maioria dos casos de uso pode ser abordada examinando / testando a url ou as request.

Um função de callback do gerenciador recebem o mesmo ExtendableEvent, Request URL objeto junto com um valor params, que é o valor retornado pelo método "match" função.

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

Seu gerenciador precisa retornar uma promessa que seja resolvida como Response. Neste exemplo, estamos usando async e await. Internamente, o valor de retorno Response será encapsulado em uma promessa.

Você pode registrar esses callbacks da seguinte forma:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb);

A única limitação é que a "correspondência" callback deve retornar de forma síncrona um verdadeiro não será possível realizar nenhum trabalho assíncrono. A razão para isso é que, o Router precisa responder de forma síncrona ao evento de busca ou permitir a queda outros eventos de busca.

Normalmente, o "manipulador" callback usaria uma das estratégias fornecidas por estratégias de caixa de trabalho, como:

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

registerRoute(matchCb, new StaleWhileRevalidate());

Nesta página, vamos nos concentrar em workbox-routing, mas você pode Saiba mais sobre essas estratégias em estratégias de caixa de trabalho.

Como registrar uma rota de expressão regular

Uma prática comum é usar uma expressão regular em vez de uma "correspondência" o retorno de chamada. O Workbox facilita a implementação dessa forma:

import {registerRoute} from 'workbox-routing';

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

Para solicitações do mesma origem, esta expressão regular corresponderá, desde que o URL da solicitação corresponda ao expressão regular.

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

No entanto, para solicitações de origem cruzada, as expressões regulares deve corresponder ao início do URL. A razão para isso é que é improvável que, com uma expressão regular new RegExp('/styles/.*\\.css') você pretendia corresponder a arquivos CSS de terceiros.

  • 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 você quis esse comportamento, só precisa garantir que a imagem expressão corresponde ao início do URL. Se quisermos corresponder para https://cdn.third-party-site.com, poderíamos usar a solicitação expressão 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 você quiser fazer a correspondência de empresas locais e de terceiros, use um caractere curinga no início da expressão regular, mas isso deve ser feito com cautela para garantir que ele não cause comportamentos inesperados no seu aplicativo da Web.

Como registrar uma rota de navegação

Caso seu site tenha um aplicativo de página única, você pode usar um NavigationRoute para retornar uma resposta específica para todos solicitações de navegação.

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

Sempre que um usuário acessar seu site no navegador, a solicitação da página será será uma solicitação de navegação e será exibida a página /app-shell.html em cache. Observação: você precisa ter a página armazenada em cache via workbox-precaching ou pela sua própria etapa de instalação.

Por padrão, isso vai responder a todas as solicitações de navegação. Se você quiser restringi-lo para responder a um subconjunto de URLs, você pode usar o allowlist e denylist para restringir quais páginas corresponderão a esse trajeto.

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

O único ponto a ser observado é que o denylist vencerá se um URL estiver em ambos a allowlist e a denylist.

Definir um gerenciador padrão

Se você quiser fornecer um "manipulador" para solicitações que não correspondem a uma rota, é possível definir um gerenciador padrão.

import {setDefaultHandler} from 'workbox-routing';

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

Definir um gerenciador de captura

Caso alguma de suas rotas gere um erro, é possível capturar e degradação suave, definindo um gerenciador de captura.

import {setCatchHandler} from 'workbox-routing';

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

Como definir uma rota para solicitações que não são GET

Por padrão, todas as rotas são consideradas para solicitações GET.

Se você quiser encaminhar outras solicitações, como POST, será necessário para definir o método ao registrar a rota, da seguinte maneira:

import {registerRoute} from 'workbox-routing';

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

Geração de registros do roteador

É possível determinar o fluxo de uma solicitação usando os registros do workbox-routing, que destaca os URLs que estão sendo processados pelo Workbox.

Registros de roteamento

Se você precisa de informações mais detalhadas, pode definir o nível de registro como debug para acessar registros das solicitações não processadas pelo roteador. Consulte nossa guia de depuração para mais informações sobre definindo o nível de registro.

Depurar e registrar mensagens de roteamento

Uso Avançado

Se você quiser ter mais controle sobre quando o roteador do Workbox recebe você pode criar suas próprias Router e chame são handleRequest() sempre que quiser usá-lo para responder a uma solicitação.

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

Ao usar Router diretamente, também será necessário usar a classe Route. ou qualquer uma das classes estendidas para registrar rotas.

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 a criação de um workbox-routing.Route que corresponde a navegador [solicitações de navegação]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests.

Ela só corresponderá às solicitações recebidas https://fetch.spec.whatwg.org/#concept-request-mode|mode é definido como navigate.

Você pode aplicar essa rota apenas a um subconjunto de solicitações de navegação usando um ou ambos os parâmetros denylist e allowlist.

Propriedades

  • construtor

    void

    Se denylist e allowlist forem fornecidos, o denylist terão precedência e a solicitação não corresponderá a essa rota.

    As expressões regulares em allowlist e denylist são combinadas com os dados concatenados [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 do URL solicitado.

    Observação: essas regex podem ser avaliadas em relação a cada URL de destino durante navegação. Evite usar RegExps complexas, Caso contrário, os usuários poderão ter atrasos ao navegar no site.

    A função constructor tem esta aparência:

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

  • catchHandler
  • correspondência
  • method

    HTTPMethod

  • setCatchHandler

    void

    A função setCatchHandler tem esta aparência:

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

    • handler

      Uma chamada de retorno função que retorna uma promessa resolvendo para uma Resposta

NavigationRouteMatchOptions

Propriedades

  • lista de permissões

    RegExp[] opcional

  • lista de bloqueio

    RegExp[] opcional

RegExpRoute

RegExpRoute facilita a criação de uma expressão regular com base workbox-routing.Route

Para solicitações de mesma origem, a RegExp só precisa corresponder a parte do URL. Para solicitações a servidores de terceiros, é necessário definir uma regex que corresponda início do URL.

Propriedades

  • construtor

    void

    Se a expressão regular contiver [grupos de captura]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references, os valores capturados serão passados para a workbox-routing~handlerCallback de params .

    A função constructor tem esta aparência:

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

    • regExp

      RegExp

      A expressão regular para correspondência com os URLs.

    • handler

      Uma chamada de retorno que retorna uma promessa resultando em uma resposta.

    • method

      HTTPMethod opcional

  • catchHandler
  • correspondência
  • method

    HTTPMethod

  • setCatchHandler

    void

    A função setCatchHandler tem esta aparência:

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

    • handler

      Uma chamada de retorno função que retorna uma promessa resolvendo para uma Resposta

Route

Um Route consiste em um par de funções de callback, "match". e "handler". A "correspondência" determina se uma rota deve ser usada para "processar" por solicitação retornando um valor não falso, se possível. O "manipulador" retorno de chamada é chamado quando há uma correspondência e precisa retornar uma promessa que seja resolvida para um Response.

Propriedades

  • construtor

    void

    Construtor da classe Route.

    A função constructor tem esta aparência:

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

    • correspondência

      Função de callback que determina se a rota corresponde a uma determinada evento fetch retornando um valor não falso.

    • handler

      Uma chamada de retorno que retorna uma promessa resolvendo para uma resposta.

    • method

      HTTPMethod opcional

  • catchHandler
  • correspondência
  • method

    HTTPMethod

  • setCatchHandler

    void

    A função setCatchHandler tem esta aparência:

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

    • handler

      Uma chamada de retorno função que retorna uma promessa resolvendo para uma Resposta

Router

O roteador pode ser usado para processar um FetchEvent usando um ou mais workbox-routing.Route, respondendo com Response se se há uma rota correspondente.

Se nenhuma rota corresponder a uma determinada solicitação, o roteador usará um "default" se um estiver definido.

Caso a rota correspondente gere um erro, o roteador usa um "catch" caso um deles esteja definido para lidar com problemas e responder com uma Solicitação.

Se uma solicitação corresponder a várias rotas, a mais antiga registrada será ser usada para responder à solicitação.

Propriedades

  • construtor

    void

    Inicializa um novo roteador.

    A função constructor tem esta aparência:

    () => {...}

  • rotas

    Map&lt;HTTPMethodRoute[]&gt;

  • addCacheListener

    void

    Adiciona um listener de eventos de mensagem para URLs que serão armazenados em cache na janela. Isso é útil para armazenar em cache os recursos carregados na página antes do momento o service worker começou a controlá-lo.

    O formato dos dados da mensagem enviados da janela deve ser o seguinte. Em que a matriz urlsToCache pode consistir em strings de URL ou uma matriz de String de URL + objeto requestInit (o mesmo que você transmitiria para fetch()).

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

    A função addCacheListener tem esta aparência:

    () => {...}

  • addFetchListener

    void

    Adiciona um listener de eventos de busca para responder a eventos quando há correspondência de uma rota da solicitação do evento.

    A função addFetchListener tem esta aparência:

    () => {...}

  • findMatchingRoute

    void

    Verifica uma solicitação e um URL (e, opcionalmente, um evento) na lista de rotas registradas e, se houver uma correspondência, retorna o nome trajeto junto com os parâmetros gerados pela correspondência.

    A função findMatchingRoute tem esta aparência:

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

    • retorna

      objeto

      Um objeto com as propriedades route e params. Eles serão preenchidos se uma rota correspondente for encontrada ou undefined caso contrário.

  • handleRequest

    void

    Aplique as regras de roteamento a um objeto FetchEvent para obter uma resposta de um o manipulador da rota apropriada.

    A função handleRequest tem esta aparência:

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

    • opções

      objeto

      • evento

        ExtendableEvent

        O evento que acionou o solicitação.

      • solicitação

        Solicitação

        A solicitação a ser processada.

    • retorna

      Promise&lt;Response&gt;

      Uma promessa é retornada se uma rota registrada pode processar a solicitação. Se não houver correspondência trajeto e não houver defaultHandler, undefined será retornado.

  • registerRoute

    void

    Registra uma rota com o roteador.

    A função registerRoute tem esta aparência:

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

    • trajeto

      A rota a ser registrada.

  • setCatchHandler

    void

    Se uma rota gerar um erro ao processar uma solicitação, essa handler será chamado e terá a chance de fornecer uma resposta.

    A função setCatchHandler tem esta aparência:

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

    • handler

      Uma chamada de retorno que retorna uma promessa resultando em uma resposta.

  • setDefaultHandler

    void

    Definir um handler padrão que é chamado quando nenhum trajeto explicitamente corresponder à solicitação recebida.

    Cada método HTTP ("GET", "POST" etc.) tem seu próprio gerenciador padrão.

    Sem um manipulador padrão, as solicitações sem correspondência irão para o como se não houvesse um service worker.

    A função setDefaultHandler tem esta aparência:

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

    • handler

      Uma chamada de retorno que retorna uma promessa resultando em uma resposta.

    • method

      HTTPMethod opcional

  • unregisterRoute

    void

    Cancela o registro de uma rota com o roteador.

    A função unregisterRoute tem esta aparência:

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

    • trajeto

      Rota para cancelar o registro.

Métodos

registerRoute()

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

Registre facilmente uma RegExp, string ou função com um armazenamento em cache para uma instância de roteador de singleton.

Este método gera um Route para você, se necessário, e chame workbox-routing.Router#registerRoute.

Parâmetros

  • capturar

    string | RegExp | RouteMatchCallback | Trajeto

    Se o parâmetro de captura for um Route, todos os outros argumentos serão ignorados.

  • handler

    RouteHandler opcional

  • method

    HTTPMethod opcional

Retorna

  • O Route gerado.

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

Se uma rota gerar um erro ao processar uma solicitação, essa handler será chamado e terá a chance de fornecer uma resposta.

Parâmetros

  • handler

    Uma chamada de retorno que retorna uma promessa resultando em uma resposta.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

Definir um handler padrão que é chamado quando nenhum trajeto explicitamente corresponder à solicitação recebida.

Sem um manipulador padrão, as solicitações sem correspondência irão para o como se não houvesse um service worker.

Parâmetros

  • handler

    Uma chamada de retorno que retorna uma promessa resultando em uma resposta.