Ограничения при работе с cross-origin ресурсами

Sw-precache — это инструмент для автоматической генерации сервис-воркеров, который позволяет кэшировать ресурсы веб-приложения и обеспечивать его работу в оффлайн-режиме. Однако при работе с cross-origin ресурсами (ресурсами, находящимися на другом домене) возникают определённые ограничения, продиктованные спецификациями браузеров и политикой безопасности CORS.


Политика CORS и её влияние на кэширование

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

  • Без соответствующих CORS-заголовков браузер не позволит сервис-воркеру получить доступ к содержимому ответа, что делает кэширование неполноценным.
  • Если ресурс доступен через кросс-доменный запрос с заголовком Access-Control-Allow-Origin, Sw-precache может безопасно его кэшировать и использовать при последующих обращениях.

Пример проблемы:

// Попытка кэшировать внешний ресурс без CORS
swPrecache.write('service-worker.js', {
  staticFileGlobs: [
    'https://cdn.example.com/library.js'
  ]
});

В этом случае при установке сервис-воркера браузер выдаст ошибку OpaqueResponse или отклонит кэширование, потому что ответ нельзя безопасно прочитать.


Поддержка opaque-ответов

Sw-precache позволяет кэшировать ресурсы с cross-origin через опцию ignoreUrlParametersMatching и работу с opaque-ответами. Opaque-ответ — это ответ, тело которого недоступно сервис-воркеру, но браузер может хранить его в кэше и отдавать клиенту.

Особенности opaque-ответов:

  • Невозможность чтения содержимого ответа.
  • Ограниченные возможности проверки актуальности данных.
  • Подходят для ресурсов, которые не требуют модификации или анализа на стороне клиента (например, шрифты, изображения).

Пример конфигурации:

swPrecache.write('service-worker.js', {
  staticFileGlobs: [
    'dist/**/*.{js,css,html}',
    'https://cdn.example.com/library.js'
  ],
  stripPrefix: 'dist/',
  handleFetch: true
});

Для внешних ресурсов рекомендуется проверять, что сервер поддерживает Access-Control-Allow-Origin: *, чтобы сервис-воркер мог безопасно использовать их содержимое без ограничений.


Ограничения при обновлении кросс-доменных ресурсов

  1. Отсутствие контроля версий С opaque-ответами сервис-воркер не видит содержимое, поэтому невозможно определить, изменился ли ресурс. Это может привести к использованию устаревшей версии при обновлении приложения.

  2. Нет возможности применения стратегии «stale-while-revalidate» Для ресурсов без CORS сервис-воркер не сможет одновременно отдавать кэшированную версию и проверять наличие новой на сервере.

  3. Ошибки при модификации ответов Любые попытки изменить opaque-ответ, например добавить заголовки или преобразовать в JSON, приведут к сбоям.


Рекомендации по работе с cross-origin ресурсами

  • Предпочтительно использовать CDN с CORS: внешний сервер должен отдавать заголовок Access-Control-Allow-Origin.
  • Минимизировать кэширование opaque-ответов для ресурсов, которые критичны для работы приложения.
  • Для библиотек и статики лучше создавать локальные копии, чтобы избежать ограничений и обеспечить корректное обновление кэша.
  • В конфигурации Sw-precache можно использовать фильтры для исключения внешних ресурсов, если они не поддерживают CORS, чтобы предотвратить ошибки при генерации сервис-воркера.

Практическое использование с CORS

const swPrecache = require('sw-precache');

swPrecache.write('service-worker.js', {
  staticFileGlobs: [
    'dist/**/*.{js,css,html}',
    'https://cdn.example.com/fonts/*.woff2'
  ],
  stripPrefix: 'dist/',
  runtimeCaching: [
    {
      urlPattern: /^https:\/\/cdn\.example\.com\/fonts\//,
      handler: 'cacheFirst',
      options: {
        cache: {
          maxEntries: 20,
          name: 'cdn-fonts-cache'
        },
        fetchOptions: {
          mode: 'cors'
        }
      }
    }
  ]
});

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


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

  • Cross-origin ресурсы без CORS ограничены в кэшировании.
  • Opaque-ответы позволяют хранить ресурс, но не дают доступа к содержимому.
  • Для критичных ресурсов рекомендуется использовать локальное копирование или CDN с поддержкой CORS.
  • Sw-precache предоставляет механизмы конфигурации runtimeCaching и fetchOptions для безопасной работы с внешними ресурсами.