Работник службы может перехватывать сетевые запросы к странице. Он может отвечать браузеру кэшированным контентом, контентом из сети или контентом, созданным в сервис-воркере.
 workbox-routing — это модуль, который позволяет легко «направлять» эти запросы к различным функциям, которые предоставляют ответы.
Как осуществляется маршрутизация
 Когда сетевой запрос вызывает событие выборки сервисного работника, workbox-routing попытается ответить на запрос, используя предоставленные маршруты и обработчики. 
Основные моменты, на которые следует обратить внимание из вышеизложенного:
- Важен метод запроса. По умолчанию маршруты регистрируются для запросов - GET. Если вы хотите перехватывать другие типы запросов, вам необходимо указать метод.
- Порядок регистрации Маршрута важен. Если зарегистрировано несколько маршрутов, которые могут обрабатывать запрос, для ответа на запрос будет использоваться тот маршрут, который зарегистрирован первым. 
Есть несколько способов зарегистрировать маршрут: вы можете использовать обратные вызовы, регулярные выражения или экземпляры Route.
Сопоставление и обработка маршрутов
«Маршрут» в рабочей области — это не что иное, как две функции: функция «сопоставления», определяющая, должен ли маршрут соответствовать запросу, и функция «обработки», которая должна обрабатывать запрос и отвечать ответом.
Workbox поставляется с некоторыми помощниками, которые будут выполнять сопоставление и обработку за вас, но если вам когда-нибудь понадобится другое поведение, лучшим вариантом будет написание собственной функции сопоставления и обработчика.
 В функцию обратного вызова match передаются ExtendableEvent , Request и объект URL , который вы можете сопоставить, вернув истинное значение. В качестве простого примера вы можете сопоставить определенный URL-адрес следующим образом:
const matchCb = ({url, request, event}) => {
  return url.pathname === '/special/url';
};
 Большинство случаев использования можно охватить путем изучения/тестирования либо url , либо request .
 Функции обратного вызова обработчика будут переданы те же объекты ExtendableEvent , Request и URL , а также значение params , которое является значением, возвращаемым функцией «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,
  });
};
 Ваш обработчик должен вернуть обещание, которое разрешается в Response . В этом примере мы используем async и await . Под капотом возвращаемое значение Response будет заключено в обещание.
Вы можете зарегистрировать эти обратные вызовы следующим образом:
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb);
 Единственное ограничение заключается в том, что обратный вызов «match» должен синхронно возвращать истинное значение, вы не можете выполнять какую-либо асинхронную работу. Причина этого в том, что Router должен синхронно реагировать на событие выборки или разрешать переход к другим событиям выборки.
Обычно обратный вызов «обработчика» использует одну из стратегий, предоставляемых стратегиями рабочего ящика, например:
import {registerRoute} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
registerRoute(matchCb, new StaleWhileRevalidate());
 На этой странице мы сосредоточимся на workbox-routing , но вы можете узнать больше об этих стратегиях на странице Workbox-strategies . 
Как зарегистрировать маршрут регулярного выражения
Обычной практикой является использование регулярного выражения вместо обратного вызова «соответствие». Workbox позволяет легко реализовать это следующим образом:
import {registerRoute} from 'workbox-routing';
registerRoute(new RegExp('/styles/.*\\.css'), handlerCb);
Для запросов из одного и того же источника это регулярное выражение будет соответствовать, если URL-адрес запроса соответствует регулярному выражению.
- https://example.com/styles/main.css
- https://example.com/styles/nested/file.css
- https://example.com/nested/styles/directory.css
 Однако для запросов из разных источников регулярные выражения должны соответствовать началу URL-адреса . Причина этого в том, что маловероятно, что с помощью регулярного выражения new RegExp('/styles/.*\\.css') вы намеревались сопоставить сторонние файлы 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
 Если вам действительно нужно такое поведение, вам просто нужно убедиться, что регулярное выражение соответствует началу URL-адреса. Если бы мы хотели сопоставить запросы https://cdn.third-party-site.com //cdn. Third-party-site.com, мы могли бы использовать регулярное выражение 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
Если вы хотите сопоставить как локальные, так и сторонние данные, вы можете использовать подстановочный знак в начале регулярного выражения, но делать это следует с осторожностью, чтобы не вызвать неожиданное поведение в вашем веб-приложении.
Как зарегистрировать навигационный маршрут
 Если ваш сайт представляет собой одностраничное приложение, вы можете использовать NavigationRoute для возврата определенного ответа на все запросы навигации .
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);
 Всякий раз, когда пользователь заходит на ваш сайт в браузере, запрос страницы будет запросом навигации, и ему будет отправлена кешированная страница /app-shell.html . (Примечание. Страница должна быть кэширована с помощью workbox-precaching или на этапе установки самостоятельно.)
 По умолчанию это будет отвечать на все запросы навигации. Если вы хотите ограничить его ответом на подмножество URL-адресов, вы можете использовать параметры allowlist и denylist чтобы ограничить, какие страницы будут соответствовать этому маршруту.
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);
 Единственное, что следует отметить, это то, что denylist выиграет, если URL-адрес находится как в списке allowlist , так и denylist .
Установить обработчик по умолчанию
Если вы хотите предоставить «обработчик» для запросов, которые не соответствуют маршруту, вы можете установить обработчик по умолчанию.
import {setDefaultHandler} from 'workbox-routing';
setDefaultHandler(({url, event, params}) => {
  // ...
});
Установите обработчик захвата
В случае, если какой-либо из ваших маршрутов выдает ошибку, вы можете корректно захватить и ухудшить ситуацию, установив обработчик catch.
import {setCatchHandler} from 'workbox-routing';
setCatchHandler(({url, event, params}) => {
  ...
});
Определение маршрута для запросов, отличных от GET
 По умолчанию предполагается, что все маршруты предназначены для запросов GET .
 Если вы хотите маршрутизировать другие запросы, например POST запрос, вам необходимо определить метод при регистрации маршрута, например: 
import {registerRoute} from 'workbox-routing';
registerRoute(matchCb, handlerCb, 'POST');
registerRoute(new RegExp('/api/.*\\.json'), handlerCb, 'POST');
Протоколирование маршрутизатора
 Вы сможете определить поток запроса, используя журналы workbox-routing , в которых будет указано, какие URL-адреса обрабатываются через Workbox. 
 Если вам нужна более подробная информация, вы можете установить уровень журнала для debug , чтобы просматривать журналы запросов, не обрабатываемых маршрутизатором. Дополнительную информацию о настройке уровня журнала см. в нашем руководстве по отладке . 
Расширенное использование
 Если вы хотите иметь больший контроль над тем, когда маршрутизатор Workbox получает запросы, вы можете создать свой собственный экземпляр Router и вызывать его метод handleRequest() всякий раз, когда вы хотите использовать маршрутизатор для ответа на запрос. 
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.
  }
});
При непосредственном использовании Router вам также потребуется использовать класс 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));
Типы
NavigationRoute
NavigationRoute упрощает создание workbox-routing.Route , соответствующего [запросам навигации] браузера https://developers.google.com/web/fundamentals/primers/service-workers/high-performance-loading#first_what_are_navigation_requests Performance-loading#first_what_are_navigation_requests .
 Он будет соответствовать только входящим запросам, для которых https://fetch.spec.whatwg.org/#concept-request-mode|mode настроен на navigate .
 При желании вы можете применить этот маршрут только к подмножеству запросов навигации, используя один или оба параметра списка denylist и allowlist . 
Характеристики
- пустота - Если указаны и - denylist, и- allowlist,- denylistбудет иметь приоритет, и запрос не будет соответствовать этому маршруту.- Регулярные выражения в - allowlistи- denylistсопоставляются с объединенными [- pathname]- https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/pathnameи [- search]- https://developer.mozilla.org/en-US/docs/Web/API/HTMLHyperlinkElementUtils/searchчастей запрошенного URL-адреса.- Примечание . Эти регулярные выражения можно оценивать по каждому целевому URL-адресу во время навигации. Избегайте использования сложных регулярных выражений , иначе ваши пользователи могут столкнуться с задержками при навигации по вашему сайту. - Функция - constructorвыглядит так:- (handler: RouteHandler, options?: NavigationRouteMatchOptions) => {...} - Функция обратного вызова, которая возвращает обещание, приводящее к ответу. 
- NavigationRouteMatchOptions необязательно 
 
- RouteHandlerObject необязательно 
- HTTPМетод 
- пустота - Функция - setCatchHandlerвыглядит так:- (handler: RouteHandler) => {...} - Функция обратного вызова, которая возвращает обещание, преобразующееся в ответ. 
 
NavigationRouteMatchOptions
Характеристики
- RegExp[] необязательно 
- RegExp[] необязательно 
RegExpRoute
RegExpRoute упрощает создание workbox-routing.Route на основе регулярных выражений.
Для запросов одного и того же происхождения RegExp должен соответствовать только части URL-адреса. Для запросов к сторонним серверам необходимо определить RegExp, соответствующий началу URL-адреса.
Характеристики
- конструкторпустота Если регулярное выражение содержит [группы захвата] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#grouping-back-references, захваченные значения будут переданы вworkbox-routing~handlerCallbackаргументparams.Функция constructorвыглядит так:(regExp: RegExp, handler: RouteHandler, method?: HTTPMethod) => {...} - регулярное выражениеРегэксп Регулярное выражение для сопоставления URL-адресов. 
- обработчикФункция обратного вызова, которая возвращает обещание, приводящее к ответу. 
- методHTTPMethod необязательно 
 - возвращает
 
- catchHandlerRouteHandlerObject необязательно 
- обработчик
- соответствовать
- методHTTPМетод 
- УстановитьCatchHandlerпустота Функция setCatchHandlerвыглядит так:(handler: RouteHandler) => {...} - обработчикФункция обратного вызова, которая возвращает обещание, преобразующееся в ответ. 
 
Route
Route состоит из пары функций обратного вызова: «match» и «handler». Обратный вызов «match» определяет, следует ли использовать маршрут для «обработки» запроса, возвращая неложное значение, если это возможно. Обратный вызов «обработчика» вызывается при обнаружении совпадения и должен возвращать Promise, который преобразуется в Response . 
Характеристики
- конструкторпустота Конструктор класса Route. Функция constructorвыглядит так:(match: RouteMatchCallback, handler: RouteHandler, method?: HTTPMethod) => {...} - соответствоватьФункция обратного вызова, которая определяет, соответствует ли маршрут данному событию fetch, возвращая неложное значение.
- обработчикФункция обратного вызова, которая возвращает обещание, преобразующееся в ответ. 
- методHTTPMethod необязательно 
 - возвращает
 
- catchHandlerRouteHandlerObject необязательно 
- обработчик
- соответствовать
- методHTTPМетод 
- УстановитьCatchHandlerпустота Функция setCatchHandlerвыглядит так:(handler: RouteHandler) => {...} - обработчикФункция обратного вызова, которая возвращает обещание, преобразующееся в ответ. 
 
Router
Маршрутизатор можно использовать для обработки FetchEvent с использованием одного или нескольких workbox-routing.Route , отвечая Response , если соответствующий маршрут существует.
Если ни один маршрут не соответствует данному запросу, Маршрутизатор будет использовать обработчик «по умолчанию», если он определен.
Если соответствующий Маршрут выдает ошибку, Маршрутизатор будет использовать обработчик «catch», если он определен для корректного решения проблем и ответа Запросом.
Если запрос соответствует нескольким маршрутам, для ответа на запрос будет использоваться самый ранний зарегистрированный маршрут.
Характеристики
- конструкторпустота Инициализирует новый маршрутизатор. Функция constructorвыглядит так:() => {...}- возвращает
 
- маршрутыКарта<HTTPMethodRoute[]> 
- добавитьCacheListenerпустота Добавляет прослушиватель событий сообщений для кэширования URL-адресов из окна. Это полезно для кэширования ресурсов, загруженных на страницу, до того, как сервис-воркер начал ею управлять. Формат данных сообщения, отправляемого из окна, должен быть следующим. Где массив urlsToCacheможет состоять из строк URL-адресов или массива строк URL-адресов + объектаrequestInit(так же, как вы передаете вfetch()).{ type: 'CACHE_URLS', payload: { urlsToCache: [ './script1.js', './script2.js', ['./script3.js', {mode: 'no-cors'}], ], }, }Функция addCacheListenerвыглядит так:() => {...}
- добавитьFetchListenerпустота Добавляет прослушиватель событий выборки для реагирования на события, когда маршрут соответствует запросу события. Функция addFetchListenerвыглядит так:() => {...}
- findMatchingRouteпустота Сверяет запрос и URL-адрес (и, при необходимости, событие) по списку зарегистрированных маршрутов и, если есть совпадение, возвращает соответствующий маршрут вместе со всеми параметрами, сгенерированными в результате совпадения. Функция findMatchingRouteвыглядит так:(options: RouteMatchCallbackOptions) => {...} - параметры
 - возвращаетобъект Объект со свойствами routeиparams. Они заполняются, если найден соответствующий маршрут, или в противном случаеundefined.
 
- handleRequestпустота Примените правила маршрутизации к объекту FetchEvent, чтобы получить ответ от соответствующего обработчика маршрута. Функция handleRequestвыглядит так:(options: object) => {...} - параметрыобъект - событиеРасширяемоеСобытие Событие, вызвавшее запрос. 
- запросЗапрос Запрос на обработку. 
 
 - возвращаетОбещание<Ответ> Промис возвращается, если зарегистрированный маршрут может обработать запрос. Если соответствующего маршрута нет и нет defaultHandler, возвращаетсяundefined.
 
- РегистрацияМаршрутпустота Регистрирует маршрут на маршрутизаторе. Функция registerRouteвыглядит так:(route: Route) => {...} - маршрутМаршрут регистрации. 
 
- УстановитьCatchHandlerпустота Если Route выдает ошибку при обработке запроса, этот handlerбудет вызван и получит возможность предоставить ответ.Функция setCatchHandlerвыглядит так:(handler: RouteHandler) => {...} - обработчикФункция обратного вызова, которая возвращает обещание, приводящее к ответу. 
 
- setDefaultHandlerпустота Определите handlerпо умолчанию, который вызывается, когда ни один маршрут явно не соответствует входящему запросу.Каждый метод HTTP («GET», «POST» и т. д.) получает свой собственный обработчик по умолчанию. Без обработчика по умолчанию несовпадающие запросы будут отправляться в сеть, как если бы там не было сервисного работника. Функция setDefaultHandlerвыглядит так:(handler: RouteHandler, method?: HTTPMethod) => {...} - обработчикФункция обратного вызова, которая возвращает обещание, приводящее к ответу. 
- методHTTPMethod необязательно 
 
- отменить регистрациюМаршрутпустота Отменяет регистрацию маршрута на маршрутизаторе. Функция unregisterRouteвыглядит так:(route: Route) => {...} - маршрутМаршрут для отмены регистрации. 
 
Методы
registerRoute()
workbox-routing.registerRoute(
capture: string | RegExp | RouteMatchCallback | Route,
handler?: RouteHandler,
method?: HTTPMethod,
): Route
Легко зарегистрировать RegExp, строку или функцию с помощью стратегии кэширования в одноэлементном экземпляре Router.
 Этот метод при необходимости сгенерирует для вас маршрут и вызовет workbox-routing.Router#registerRoute . 
Параметры
- захватыватьстрока | регэксп | МаршрутМатчОбратный вызов | Маршрут Если параметр захвата — Route, все остальные аргументы будут игнорироваться.
- обработчикRouteHandler необязательно 
- методHTTPMethod необязательно 
Возврат
- Сгенерированный - Route.
setCatchHandler()
workbox-routing.setCatchHandler(
handler: RouteHandler,
): void
 Если Route выдает ошибку при обработке запроса, этот handler будет вызван и получит возможность предоставить ответ. 
Параметры
- обработчикФункция обратного вызова, которая возвращает обещание, приводящее к ответу. 
setDefaultHandler()
workbox-routing.setDefaultHandler(
handler: RouteHandler,
): void
 Определите handler по умолчанию, который вызывается, когда ни один маршрут явно не соответствует входящему запросу.
Без обработчика по умолчанию несовпадающие запросы будут отправляться в сеть, как если бы там не было сервисного работника.
Параметры
- обработчикФункция обратного вызова, которая возвращает обещание, приводящее к ответу.