Политика CORS и сервис-воркер

Политика CORS (Cross-Origin Resource Sharing) определяет правила доступа веб-приложений к ресурсам, расположенным на других доменах. В контексте сервис-воркеров это критически важно, так как воркер может перехватывать запросы и кэшировать ресурсы, включая те, которые находятся на внешних серверах. Браузеры блокируют попытки получить доступ к ресурсам другого происхождения без корректно настроенных заголовков CORS, что предотвращает утечку данных и защищает от атак типа CSRF.

При регистрации сервис-воркера важно учитывать, что воркер действует в контексте origin страницы. Это означает, что запросы к сторонним API должны сопровождаться соответствующими заголовками Access-Control-Allow-Origin. Без них Workbox не сможет корректно кэшировать такие ресурсы, и при попытке сделать fetch будет выброшена ошибка CORS.

Использование Workbox для работы с кросс-доменными ресурсами

Workbox предоставляет набор высокоуровневых API для настройки стратегии кэширования и управления сетевыми запросами, включая поддержку кросс-доменных запросов. Основные моменты:

  1. Стратегии кэширования Workbox позволяет выбрать подходящую стратегию для каждого типа ресурса:

    • NetworkFirst — сначала сетевой запрос, fallback на кэш;
    • CacheFirst — сначала кэш, fallback на сеть;
    • StaleWhileRevalidate — отдача из кэша с асинхронным обновлением;
    • NetworkOnly и CacheOnly — прямой контроль, без fallback.

    Для кросс-доменных ресурсов рекомендуется использовать стратегии с проверкой заголовков CORS, чтобы не получить ошибку при попытке сохранения в кэш.

  2. Настройка fetch с CORS При регистрации маршрутов в Workbox можно указывать опции для fetch-запросов:

    workbox.routing.registerRoute(
      ({url}) => url.origin === 'https://api.example.com',
      new workbox.strategies.NetworkFirst({
        cacheName: 'external-api-cache',
        fetchOptions: {
          mode: 'cors',
          credentials: 'include'
        }
      })
    );

    Ключевые моменты:

    • mode: 'cors' сообщает браузеру, что запрос к другому origin разрешен;
    • credentials: 'include' позволяет передавать cookies и авторизационные заголовки.
  3. Обработка ошибок CORS Если сервер не возвращает корректные заголовки CORS, запросы будут отвергнуты. Workbox предоставляет механизм перехвата ошибок через метод catch стратегии:

    const networkFirstStrategy = new workbox.strategies.NetworkFirst({
      cacheName: 'example-cache'
    });
    
    networkFirstStrategy.handle({request: fetchEvent.request})
      .catch(error => {
        console.error('Ошибка CORS или сети:', error);
        return caches.match('/offline.html');
      });

Кэширование кросс-доменных ресурсов

Workbox поддерживает кэширование внешних ресурсов, но для этого необходимо:

  • Убедиться, что ресурс доступен через CORS;
  • Указать корректные fetchOptions при регистрации стратегии;
  • Настроить политику очистки кэша (cacheExpiration) для управления размером и сроком хранения.

Пример с кэшированием изображений с внешнего CDN:

workbox.routing.registerRoute(
  ({request}) => request.destination === 'image',
  new workbox.strategies.CacheFirst({
    cacheName: 'cdn-images-cache',
    fetchOptions: {mode: 'cors'},
    plugins: [
      new workbox.expiration.ExpirationPlugin({
        maxEntries: 50,
        maxAgeSeconds: 30 * 24 * 60 * 60 // 30 дней
      })
    ]
  })
);

Важность заголовков CORS при предзагрузке (precache)

При использовании workbox-precaching важно учитывать, что ресурсы, загружаемые с других origin, должны поддерживать CORS. В противном случае воркер не сможет их корректно кэшировать. Пример конфигурации:

workbox.precaching.precacheAndRoute([
  {url: 'https://cdn.example.com/script.js', revision: '1234'}
], {
  // Для внешних ресурсов устанавливаем fetchOptions
  fetchOptions: {mode: 'cors'}
});

Особенности безопасного взаимодействия сервис-воркера и CORS

  • Сервис-воркер не может игнорировать политику CORS браузера. Все запросы к другим доменам должны иметь корректные заголовки от сервера.
  • Использование no-cors режима позволяет получить ответ, но он будет недоступен для чтения из воркера, что ограничивает возможности кэширования.
  • Для API с авторизацией нужно использовать credentials: 'include' и убедиться, что сервер возвращает Access-Control-Allow-Credentials: true.

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

  • Всегда проверять, что сторонний ресурс поддерживает CORS перед добавлением его в стратегии Workbox.
  • Для критических данных использовать сервер-посредник (proxy) на собственном origin, чтобы избежать проблем с CORS.
  • Использовать плагины Workbox (ExpirationPlugin, CacheableResponsePlugin) для контроля кэширования и обработки ошибок сети или политики CORS.

Работа сервис-воркера с кросс-доменными ресурсами требует тщательной настройки заголовков и стратегий кэширования, и Workbox предоставляет инструменты для гибкого управления этим процессом, минимизируя риски отказа в доступе из-за политики безопасности браузера.