Как кэшировать внешние URL-адреса с помощью service worker?

Я играл с Google Web Starter Kit (https://github.com/google/web-starter-kit) и получили немного прогрессивное веб-приложение, но я застрял на одном: кэширование статических файлов с внешних CDNs. Например. Я использую значки MDL изhttps://fonts.googleapis.com/icon?family=Material + иконки я не вижу способа кэшировать запрос, поскольку работник службы отвечает только на URL-адреса в моем домене приложения.

опции, которые я вижу: 1. Скачать файл и поместите его в папку поставщика. Преимущества: простота настройки кэша SW. Недостатки: файл не будет обновляться по мере добавления новых значков (хотя это не имеет значения, поскольку мой код будет использовать только доступные значки).

  1. используйте РЕПО NPM:https://www.npmjs.com/package/material-design-icons и используйте шаг сборки для копирования CSS-файла из node_modules. Преимущества: позволит автоматически обновлять из NPM. Недостатки: немного сложнее установить вверх.

  2. какой-то причудливый прокси-метод, который позволит мне использовать SW для кэширования внешнего URL-адреса. например myapp.com/loadExternal?url=https://fonts.googleapis.com/icon?family=Material+Icons

Я склоняюсь к 2 прямо сейчас, но было бы здорово узнать, возможно ли 3.

4 ответов


Я читала SW-toolbox docs и понял, как это сделать. Просто нужно было добавить это в мое кэширование во время выполнения:

// cache fonts hosted on google CDN
global.toolbox.router.get(/googleapis/, global.toolbox.fastest);

С Google Docs:

по умолчанию извлечение ресурса из стороннего URL-адреса завершится ошибкой, если он не поддерживает CORS. Вы можете добавить no-CORS опция запроса для преодоления этого, хотя это вызовет "непрозрачный" ответ, что означает, что вы не сможете сказать, был ли ответ успешным или нет.

вот такой код:

var CACHE_NAME = 'my-site-cache-v1';
var urlsToPrefetch = [
  '/',
  '/styles/main.css',
  '/script/main.js'
];

self.addEventListener('install', function(event) {
  // Perform install steps
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        console.log('Opened cache');
        // Magic is here. Look the  mode: 'no-cors' part.
        cache.addAll(urlsToPrefetch.map(function(urlToPrefetch) {
           return new Request(urlToPrefetch, { mode: 'no-cors' });
        })).then(function() {
          console.log('All resources have been fetched and cached.');
        });
      })
  );
});

Как сказал OP, когда ресурс обновляется, трудно получить последнюю копию в этом сценарий.


Я не вижу способа кэшировать запрос только как работник службы отвечает на URL-адреса в домене моего приложения.

это неправильно. Работник службы, который активно контролирует страницу, будет иметь возможность перехватывать сетевые запросы на ресурсы перекрестного происхождения и отвечать на них; стандарт fetch событие будет срабатывать, и event.request.mode будет "cors" или "no-cors" в зависимости от контекста запроса, сделанного страница.

короче говоря, пока есть сервисный работник, контролирующий страницу, когда эта страница делает какой - либо сетевой запрос для ресурса того же или перекрестного происхождения, сервисный работник сможет ответить на fetch событие.


Я могу быть смещен, но так ли это просто, как следующее?

  caches.open(version)
  .then(function(cache) {
    return cache.addAll([
      '/',
      'index.html',
      '/css/app.css',
      '/js/app.min.js',
      '/assets/images/logo_target_white.png',
      '/scripts/angular-jwt.min.js',
      '/scripts/ng-file-upload.min.js',

       // this guy here
      'https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css'
    ]);
  })

использование этого метода и проверка моего кэша приложений в инструментах chrome, похоже, показывают его кэширование правильно.