routing skrzynki roboczej

Skrypt service worker może przechwytywać żądania sieciowe dotyczące strony. Może odpowiadać przeglądarce, umieszczając w pamięci podręcznej treści z pamięci podręcznej, treści z sieci lub treści wygenerowane w skrypcie service worker.

workbox-routing to moduł, który ułatwia „przekierowywanie” tych żądań do różnych funkcji, które odpowiadają.

Jak jest wykonywane kierowanie

Gdy żądanie sieciowe spowoduje zdarzenie pobierania skryptu service worker, workbox-routing spróbuje na nie odpowiedzieć, korzystając z podanych tras i modułów obsługi.

Diagram routingu Workbox

Najważniejsze kwestie, o których należy pamiętać:

  • Metoda żądania jest ważna. Domyślnie trasy są rejestrowane dla żądań GET. Jeśli chcesz przechwytywać żądania innego typu, musisz określić metodę.

  • Kolejność rejestracji trasy jest ważna. Jeśli zarejestrowanych jest wiele tras, które mogą obsłużyć żądanie, w odpowiedzi na to żądanie zostanie użyta trasa zarejestrowana jako pierwsza.

Istnieje kilka sposobów zarejestrowania trasy: możesz użyć wywołań zwrotnych, wyrażeń regularnych lub instancji trasy.

Dopasowywanie i obsługa na trasach

„Trasa” w polu roboczym to co najwyżej 2 funkcje: funkcja „pasująca”, która określa, czy trasa powinna pasować do żądania, oraz funkcja „obsługa”, która powinna obsłużyć żądanie i odpowiedzieć.

Workbox zawiera elementy pomocnicze, które będą dopasowywać i obsługiwać. Jeśli jednak zechcesz zmienić sposób działania, najlepszym rozwiązaniem będzie napisanie niestandardowej funkcji dopasowania i modułu obsługi.

Funkcja wywołania zwrotnego dopasowanego jest przekazywana do ExtendableEvent, Request oraz obiektu URL, które możesz dopasować, zwracając wartość prawda. Prostym przykładem może być dopasowanie dopasowania do konkretnego adresu URL, takiego jak:

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

W większości przypadków użycia można badać / testować url lub request.

Funkcja wywołania zwrotnego modułu obsługi otrzyma te same wartości ExtendableEvent, Request i URL obiekt wraz z wartością params, która jest wartością zwracaną przez funkcję „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,
  });
};

Moduł obsługi musi zwracać obietnicę, która zwraca wartość Response. W tym przykładzie używamy async i await. W tle zwracana wartość Response zostanie zawarta w obietnicy.

Możesz zarejestrować te wywołania zwrotne w następujący sposób:

import {registerRoute} from 'workbox-routing';

registerRoute(matchCb, handlerCb);

Jedynym ograniczeniem jest to, że wywołanie zwrotne „pasujące” musi synchronicznie zwracać wartość prawdziwą. Nie można wykonywać żadnych czynności asynchronicznych. Powodem jest to, że obiekt Router musi synchronicznie odpowiadać na zdarzenie pobierania lub umożliwiać przechodzenie na inne zdarzenia pobierania.

Normalnie wywołanie zwrotne „modułu obsługi” używa jednej ze strategii oferowanych przez strategie robocze, na przykład:

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

registerRoute(matchCb, new StaleWhileRevalidate());

Na tej stronie skupimy się na strategii workbox-routing, ale możesz dowiedzieć się więcej o tych strategiach związanych ze strategiami skrzynki roboczej.

Jak zarejestrować trasę wyrażenia regularnego

Powszechną praktyką jest używanie wyrażenia regularnego zamiast wywołania zwrotnego „match”. Workbox ułatwia wdrożenie w następujący sposób:

import {registerRoute} from 'workbox-routing';

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

W przypadku żądań z tego samego źródła to wyrażenie regularne będzie dopasowywane, o ile adres URL żądania pasuje do wyrażenia regularnego.

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

W przypadku żądań z innych domen wyrażenia regularne muszą jednak odpowiadać początkowi adresu URL. Jest tak mało prawdopodobne, że użycie wyrażenia regularnego new RegExp('/styles/.*\\.css') ma na celu dopasowanie plików CSS innych firm.

  • 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

Jeśli chcesz, aby takie działanie miało takie działanie, musisz się tylko upewnić, że wyrażenie regularne odpowiada początkowi adresu URL. Aby dopasować żądania do funkcji https://cdn.third-party-site.com, możemy użyć wyrażenia regularnego 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

Jeśli chcesz dopasować zarówno informacje lokalne, jak i zewnętrzne, możesz na początku wyrażenia regularnego użyć symbolu wieloznacznego, ale musisz zachować ostrożność, aby nie wywoływać nieoczekiwanych zachowań w Twojej aplikacji internetowej.

Jak zarejestrować trasę nawigacji

Jeśli Twoja witryna składa się z aplikacji składającej się z jednej strony, możesz użyć tagu NavigationRoute, aby zwrócić określoną odpowiedź na wszystkie żądania nawigacji.

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

Za każdym razem, gdy użytkownik otworzy Twoją witrynę w przeglądarce, żądanie strony będzie dotyczyło żądania nawigacji i wyświetli się strona /app-shell.html zapisana w pamięci podręcznej. Uwaga: strona powinna być zapisana w pamięci podręcznej za pomocą programu workbox-precaching lub wykonania własnego kroku instalacji.

Domyślnie odpowiedź będzie na wszystkie żądania nawigacji. Jeśli chcesz ograniczyć możliwość odpowiadania na podzbiór adresów URL, możesz użyć opcji allowlist i denylist, aby określić, które strony pasują do tej trasy.

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

Trzeba pamiętać, że wygrana denylist będzie tylko wtedy, gdy adres URL znajdzie się zarówno w polu allowlist, jak i w denylist.

Ustaw domyślny moduł obsługi

Jeśli chcesz podać „moduł obsługi” żądań, które nie pasują do trasy, możesz ustawić domyślny moduł obsługi.

import {setDefaultHandler} from 'workbox-routing';

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

Ustaw moduł obsługi przechwytywania

Jeśli któraś z Twoich tras generuje błąd, możesz przechwycić i obniżyć ją z zachowaniem płynności, ustawiając moduł obsługi przechwytywania.

import {setCatchHandler} from 'workbox-routing';

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

Definiowanie trasy dla żądań innych niż GET

Domyślnie przyjmuje się, że wszystkie trasy są przeznaczone dla żądań GET.

Jeśli chcesz kierować inne żądania, na przykład żądanie POST, musisz zdefiniować metodę podczas rejestrowania trasy, na przykład:

import {registerRoute} from 'workbox-routing';

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

Logowanie routera

Powinno być możliwe określenie przepływu żądania za pomocą logów z workbox-routing, które wskażą, które adresy URL są przetwarzane za pomocą Workbox.

Logi routingu

Jeśli potrzebujesz bardziej szczegółowych informacji, możesz ustawić poziom logowania na debug, aby wyświetlać logi żądań, które nie są obsługiwane przez router. Więcej informacji o ustawianiu poziomu logowania znajdziesz w przewodniku na temat debugowania.

Komunikaty debugowania i routingu

Zaawansowane użycie

Jeśli chcesz mieć większą kontrolę nad tym, kiedy router Workbox Router otrzymuje żądania, możesz utworzyć własną instancję Router i wywoływać jej metodę handleRequest() za każdym razem, gdy chcesz odpowiadać na żądania za pomocą routera.

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

Jeśli bezpośrednio używasz Router, musisz też rejestrować trasy za pomocą klasy Route lub dowolnych klas rozszerzających.

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

Typy

NavigationRoute

NavigationRoute ułatwia tworzenie workbox-routing.Route dopasowanych do [żądań nawigacji]https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests w przeglądarce.

Dopasowuje tylko Żądania przychodzące, których https://fetch.spec.whatwg.org/#concept-request-mode|mode ma wartość navigate.

Opcjonalnie możesz zastosować tę trasę tylko do podzbioru żądań nawigacyjnych, używając jednego lub obu parametrów denylist oraz allowlist.

Właściwości

  • konstruktor

    void

    Jeśli podasz zarówno zasady denylist, jak i allowlist, właściwość denylist będzie miała pierwszeństwo, a żądanie nie będzie pasować do tej trasy.

    Wyrażenia regularne w allowlist i denylist są dopasowywane do połączonych części żądanego adresu URL ([pathname]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathname i [search]https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/search).

    Uwaga: te wyrażenia regularne mogą być oceniane w odniesieniu do każdego docelowego adresu URL podczas nawigacji. Unikaj złożonych wyrażeń regularnych, ponieważ w przeciwnym razie użytkownicy mogą zauważyć opóźnienia w poruszaniu się po witrynie.

    Funkcja constructor wygląda tak:

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

  • catchHandler
  • moduł obsługi
  • dopasowanie
  • method

    HTTPMethod

  • setCatchHandler

    void

    Funkcja setCatchHandler wygląda tak:

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

    • moduł obsługi

      z funkcją wywołania zwrotnego, która zwraca obiecywanie na odpowiedź

NavigationRouteMatchOptions

Właściwości

  • lista dozwolonych

    RegExp[] opcjonalny

  • lista odrzuconych

    RegExp[] opcjonalny

RegExpRoute

RegExpRoute ułatwia tworzenie wyrażeń regularnych na podstawie workbox-routing.Route.

W przypadku żądań z tej samej domeny wyrażenie regularne musi pasować tylko do części adresu URL. W przypadku żądań wysyłanych do serwerów firm zewnętrznych musisz zdefiniować wyrażenie regularne pasujące do początku adresu URL.

Właściwości

  • konstruktor

    void

    Jeśli wyrażenie regularne zawiera [capture groups]https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references, przechwycone wartości zostaną przekazane do argumentu workbox-routing~handlerCallback params.

    Funkcja constructor wygląda tak:

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

    • regExp

      RegExp

      Wyrażenie regularne dopasowane do adresów URL.

    • moduł obsługi

      to funkcja wywołania zwrotnego, która zwraca obietnicę generującą odpowiedź.

    • method

      HTTPMethod opcjonalny

  • catchHandler
  • moduł obsługi
  • dopasowanie
  • method

    HTTPMethod

  • setCatchHandler

    void

    Funkcja setCatchHandler wygląda tak:

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

    • moduł obsługi

      z funkcją wywołania zwrotnego, która zwraca obiecywanie na odpowiedź

Route

Route składa się z pary funkcji wywołania zwrotnego – „match” i „handler”. Wywołanie zwrotne „pasujące” określa, czy należy użyć trasy do „obsługi” żądania, zwracając w miarę możliwości wartość inną niż fałszywa. Wywołanie zwrotne „modułu obsługi” jest wywoływane, gdy występuje dopasowanie, i powinno zwracać obietnicę, która zwraca wartość Response.

Właściwości

  • konstruktor

    void

    Konstruktor klasy trasy.

    Funkcja constructor wygląda tak:

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

    • dopasowanie

      Funkcja wywołania zwrotnego, która określa, czy trasa pasuje do danego zdarzenia fetch, zwracając wartość inną niż fałszywa.

    • moduł obsługi

      to funkcja wywołania zwrotnego, która zwraca obiecację odpowiedzialną.

    • method

      HTTPMethod opcjonalny

  • catchHandler
  • moduł obsługi
  • dopasowanie
  • method

    HTTPMethod

  • setCatchHandler

    void

    Funkcja setCatchHandler wygląda tak:

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

    • moduł obsługi

      z funkcją wywołania zwrotnego, która zwraca obiecywanie na odpowiedź

Router

Można użyć routera do przetworzenia elementu FetchEvent za pomocą co najmniej 1 komponentu workbox-routing.Route. W odpowiedzi na pytanie z użyciem routera Response, jeśli istnieje pasująca trasa, można użyć routera.

Jeśli żadna trasa nie pasuje do danego żądania, router użyje „domyślnego” modułu obsługi (jeśli został zdefiniowany).

Jeśli pasująca trasa spowoduje błąd, router użyje modułu obsługi „catch” (o ile został zdefiniowany), aby płynnie rozwiązywać problemy i odpowiadać na żądania.

Jeśli żądanie pasuje do kilku tras, w odpowiedzi na to żądanie używana jest najwcześniejsza zarejestrowana trasa.

Właściwości

  • konstruktor

    void

    Inicjuje nowego routera.

    Funkcja constructor wygląda tak:

    ()=> {...}

  • trasy

    Map<HTTPMethodRoute[]>

  • addCacheListener

    void

    Dodaje detektor zdarzeń wiadomości dla adresów URL do pamięci podręcznej z okna. Przydaje się to do buforowania zasobów załadowanych na stronie, zanim skrypt service worker zaczął ją kontrolować.

    Dane wiadomości wysyłane z okna powinny mieć następujący format: Gdzie tablica urlsToCache może się składać z ciągów adresów URL lub tablicy z ciągiem adresu URL + obiektem requestInit (tak samo jak w przypadku funkcji fetch()).

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

    Funkcja addCacheListener wygląda tak:

    ()=> {...}

  • addFetchListener

    void

    Dodaje detektor zdarzeń pobierania, który odpowiada na zdarzenia, gdy trasa pasuje do żądania zdarzenia.

    Funkcja addFetchListener wygląda tak:

    ()=> {...}

  • findMatchingRoute

    void

    Sprawdza żądanie i adres URL (oraz opcjonalnie zdarzenie) z listą zarejestrowanych tras i w razie wystąpienia dopasowania zwraca odpowiednią trasę wraz ze wszystkimi parametrami wygenerowanymi przez dopasowanie.

    Funkcja findMatchingRoute wygląda tak:

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

    • returns

      obiekt

      Obiekt z właściwościami route i params. Te pola są wypełniane, jeśli znaleziono pasującą trasę, lub undefined.

  • handleRequest

    void

    Zastosuj reguły routingu do obiektu FetchEvent, aby uzyskać odpowiedź z odpowiedniego modułu obsługi trasy.

    Funkcja handleRequest wygląda tak:

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

    • Opcje

      obiekt

      • event

        ExtendableEvent

        Zdarzenie, które wywołało żądanie.

      • Poproś

        Prośba

        Żądanie do przetworzenia.

    • returns

      Obietnica<Response>

      Obietnica jest zwracana, jeśli zarejestrowana trasa może obsłużyć żądanie. Jeśli nie ma pasującej trasy ani defaultHandler, zwracany jest wynik undefined.

  • registerRoute

    void

    Rejestruje trasę na routerze.

    Funkcja registerRoute wygląda tak:

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

    • trasa

      Ścieżka do rejestracji.

  • setCatchHandler

    void

    Jeśli podczas obsługi żądania trasa zgłosi błąd, element handler zostanie wywołany i będzie mieć możliwość udzielenia odpowiedzi.

    Funkcja setCatchHandler wygląda tak:

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

    • moduł obsługi

      to funkcja wywołania zwrotnego, która zwraca obietnicę generującą odpowiedź.

  • setDefaultHandler

    void

    Określ domyślny handler, który będzie wywoływany, gdy żadna trasa wyraźnie nie pasuje do żądania przychodzącego.

    Każda metoda HTTP („GET”, „POST” itp.) otrzymuje własny domyślny moduł obsługi.

    Bez domyślnego modułu obsługi niedopasowane żądania są wysyłane do sieci tak, jakby nie było skryptu service worker.

    Funkcja setDefaultHandler wygląda tak:

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

    • moduł obsługi

      to funkcja wywołania zwrotnego, która zwraca obietnicę generującą odpowiedź.

    • method

      HTTPMethod opcjonalny

  • unregisterRoute

    void

    Wyrejestrowuje trasę na routerze.

    Funkcja unregisterRoute wygląda tak:

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

    • trasa

      Trasa do wyrejestrowania.

Metody

registerRoute()

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

Możesz łatwo zarejestrować wyrażenie regularne, ciąg znaków lub funkcję za pomocą strategii buforowania w instancji routera typu singleton Router.

Ta metoda w razie potrzeby wygeneruje trasę i wywoła polecenie workbox-routing.Router#registerRoute.

Parametry

  • zdjęcie

    Jeśli parametr przechwytywania to Route, wszystkie pozostałe argumenty będą ignorowane.

  • moduł obsługi

    Opcjonalny RouteHandler

  • method

    HTTPMethod opcjonalny

Akcje powrotne

  • Wygenerowany Route.

setCatchHandler()

workbox-routing.setCatchHandler(
  handler: RouteHandler,
)

Jeśli podczas obsługi żądania trasa zgłosi błąd, element handler zostanie wywołany i będzie mieć możliwość udzielenia odpowiedzi.

Parametry

  • moduł obsługi

    to funkcja wywołania zwrotnego, która zwraca obietnicę generującą odpowiedź.

setDefaultHandler()

workbox-routing.setDefaultHandler(
  handler: RouteHandler,
)

Określ domyślny handler, który będzie wywoływany, gdy żadna trasa wyraźnie nie pasuje do żądania przychodzącego.

Bez domyślnego modułu obsługi niedopasowane żądania są wysyłane do sieci tak, jakby nie było skryptu service worker.

Parametry

  • moduł obsługi

    to funkcja wywołania zwrotnego, która zwraca obietnicę generującą odpowiedź.