Исключения из навигационных маршрутов

Workbox предоставляет мощные инструменты для построения сервис-воркеров и управления кэшированием ресурсов. Одной из ключевых возможностей является маршрутизация запросов, включая navigation routes — специальные маршруты, которые обрабатывают навигационные запросы браузера, например, переходы по URL, и возвращают заранее определённый HTML-файл, часто index.html для SPA-приложений. Однако в ряде случаев необходимо исключить определённые URL из обработки навигационными маршрутами, чтобы запросы к ним проходили без вмешательства сервис-воркера.

Настройка навигационных маршрутов

Навигационные маршруты в Workbox создаются с помощью функции registerRoute и класса NavigationRoute:

import { registerRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';
import { NavigationRoute } from 'workbox-routing';

const navigationRoute = new NavigationRoute(
  new NetworkFirst({
    cacheName: 'pages-cache',
  })
);

registerRoute(navigationRoute);

По умолчанию такой маршрут будет перехватывать все навигационные запросы. Для исключения определённых URL необходимо использовать параметр denylist.

Параметр denylist

denylist — это массив или регулярное выражение, которые описывают URL, исключённые из навигационного маршрута. Любой запрос, совпадающий с правилами denylist, не будет обрабатываться маршрутом.

Пример использования:

import { NavigationRoute } from 'workbox-routing';
import { NetworkFirst } from 'workbox-strategies';

const navigationRoute = new NavigationRoute(
  new NetworkFirst({
    cacheName: 'pages-cache',
  }),
  {
    denylist: [
      new RegExp('^/api/'),           // Исключение всех API-запросов
      new RegExp('\\.json$'),          // Исключение запросов к JSON-файлам
      new RegExp('^/admin/.*'),        // Исключение административной панели
    ]
  }
);

registerRoute(navigationRoute);

В этом примере навигационный маршрут будет игнорировать все URL, начинающиеся с /api/, все запросы к JSON-файлам и все пути, относящиеся к административной панели.

Параметр allowlist

Противоположностью denylist является allowlist. Он используется для явного указания URL, которые должны обрабатываться навигационным маршрутом. Если allowlist используется, все остальные запросы будут исключены.

Пример:

const navigationRoute = new NavigationRoute(
  new NetworkFirst({
    cacheName: 'pages-cache',
  }),
  {
    allowlist: [
      new RegExp('^/app/'),          // Обрабатываются только маршруты SPA
      new RegExp('^/dashboard/'),    // Обрабатываются только определённые страницы
    ]
  }
);

Использование allowlist удобно, когда количество исключений меньше, чем обрабатываемых URL.

Комбинирование allowlist и denylist

Workbox позволяет одновременно использовать оба параметра. В этом случае сначала проверяется allowlist, затем denylist. Запрос будет обработан только если он соответствует allowlist и не совпадает с denylist:

const navigationRoute = new NavigationRoute(
  new NetworkFirst({
    cacheName: 'pages-cache',
  }),
  {
    allowlist: [/^\/app\//],
    denylist: [/^\/app\/private\//]
  }
);

В данном случае сервис-воркер обработает все URL, начинающиеся с /app/, кроме /app/private/ и всех его подмаршрутов.

Исключение запросов по функциям

Помимо регулярных выражений Workbox поддерживает функции обратного вызова для более гибкой логики исключений:

const navigationRoute = new NavigationRoute(
  new NetworkFirst({
    cacheName: 'pages-cache',
  }),
  {
    denylist: [
      ({url}) => url.pathname.startsWith('/internal/') // Исключение динамически
    ]
  }
);

Функция получает объект context, содержащий url, и возвращает true, если запрос должен быть исключён.

Практические рекомендации

  • API и JSON: всегда исключать API-запросы и ресурсы, возвращающие JSON, чтобы не ломать функциональность фронтенда.
  • Админ-панели: рекомендуется использовать отдельные маршруты и исключать административные URL из SPA-навигации.
  • Динамическое исключение: функции обратного вызова позволяют реализовать сложные правила, например, исключение по авторизации пользователя.
  • Тестирование: после добавления denylist или allowlist важно проверить все навигационные переходы, чтобы убедиться, что маршруты SPA работают корректно, а исключённые ресурсы загружаются напрямую.

Заключение по использованию исключений

Использование denylist, allowlist и функций обратного вызова позволяет гибко управлять навигационными маршрутами, предотвращать перехват нежелательных запросов сервис-воркером и обеспечивать корректную работу SPA вместе с API и административными страницами. Это ключевой инструмент для стабильного кэширования и маршрутизации в современных веб-приложениях.