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.
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.
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.
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
-
void
Jeśli podasz zarówno zasady
denylist
, jak iallowlist
, właściwośćdenylist
będzie miała pierwszeństwo, a żądanie nie będzie pasować do tej trasy.Wyrażenia regularne w
allowlist
idenylist
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) => {...}
-
to funkcja wywołania zwrotnego, która zwraca obietnicę generującą odpowiedź.
-
opcjonalnie NavigationRouteMatchOptions.
-
-
Opcjonalny RouteHandlerObject
-
HTTPMethod
-
void
Funkcja
setCatchHandler
wygląda tak:(handler: RouteHandler) => {...}
-
z funkcją wywołania zwrotnego, która zwraca obiecywanie na odpowiedź
-
NavigationRouteMatchOptions
Właściwości
-
RegExp[] opcjonalny
-
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 argumentuworkbox-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
-
returns
-
-
catchHandler
Opcjonalny RouteHandlerObject
-
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
-
returns
-
-
catchHandler
Opcjonalny RouteHandlerObject
-
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:() => {...}
-
returns
-
-
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 + obiektemrequestInit
(tak samo jak w przypadku funkcjifetch()
).{ 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
iparams
. Te pola są wypełniane, jeśli znaleziono pasującą trasę, lubundefined
.
-
-
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 wynikundefined
.
-
-
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
string | RegExp | RouteMatchCallback | Trasa
Jeśli parametr przechwytywania to
Route
, wszystkie pozostałe argumenty będą ignorowane. -
moduł obsługi
Opcjonalny RouteHandler
-
method
HTTPMethod opcjonalny
Zwroty
-
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ź.