Сервисный работник с плагином запросов диапазона: не может получать mp3-файлы в автономном режиме - PullRequest
1 голос
/ 26 мая 2020

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

Первоначальная настройка и проблема: Я использовал приложение create-react-app, чтобы настроить основы, затем использовал response-app-rewired, чтобы заменить плагин GenerateSW на InjectManifest и выполнить простой preacheAndRoute манифеста, сгенерированного webpack, в моем сервис-воркере.

Работал как шарм, за исключением моих mp3-файлов: в Safari я не мог видеть длительность трека, а индикатор выполнения был мертв. В Chrome это было более-менее нормально, проблема только в том, что он обрезал последние 1-2 секунды при воспроизведении аудиофайла.

Исходное решение: В моей конфигурации ПО я добавил спецификатор c registerRoute для mp3-файлов, которые использовали плагин запроса диапазона согласно https://developers.google.com/web/tools/workbox/guides/advanced-recipes#cached -av . Это вроде сработало, теперь все работает нормально и в Chrome, и в Safari, пока я в сети. Когда я go не в сети, все, кроме mp3-файлов, можно извлечь из кеша.

Вы можете увидеть ошибку her: https://cgl-hunter-kids-test.firebaseapp.com/ Нажмите на изображение заголовка, чтобы ввести сайт, выберите «Историю» в верхнем левом меню, а затем выберите любую из 9 доступных историй. Аудиоплеер находится в правом верхнем углу.

В инструментах Chrome dev я вижу, что он извлекает файлы mp3 от Service Worker, когда он онлайн. Я также вижу, что файлы mp3 действительно существуют в предварительном кеше. Понятия не имею, почему он не может их найти в автономном режиме - может ли кто-нибудь помочь?

Спасибо, Диана

Конфигурация моего сервис-воркера:

const COOKIE_CONSENT_ENDPOINT = '/hunterkidsCookieConsent';
const GAME_DATA_ENDPOINT      = '/hunterkidsGameData';

/* Use client claim to handle SW updates */
workbox.core.clientsClaim();

/* Activate new SW (user triggered) */
self.addEventListener('message', (event) => {
    if (event.data.action === 'skipWaiting') self.skipWaiting();
});

/* Cache files from _precacheManifest (generated by InjectManifest webpack plugin) */
self.__precacheManifest = [].concat(self.__precacheManifest || []);

self.addEventListener('activate', (event) => {event.waitUntil(clients.claim());});

/* Handle ranged quests of mp3 files */
// https://github.com/GoogleChrome/workbox/issues/1644
// https://developers.google.com/web/tools/workbox/guides/advanced-recipes#cached-av
workbox.routing.registerRoute(
  ({url}) => url.pathname.endsWith('.mp3'),
  new workbox.strategies.CacheFirst({
    cacheName: workbox.core.cacheNames.precache,
    plugins: [     
        new workbox.cacheableResponse.Plugin({ statuses: [200] }),
        new workbox.rangeRequests.Plugin(),
      ],
  })
);

/* Special fetch requests */
self.addEventListener('fetch', function(event) {
    const {
        request,
        request: {url, method},
  } = event;
  /* Game progress */
  if (url.match(GAME_DATA_ENDPOINT)) {
    if (method === 'POST') {
      /* Write data to cache */
      request.json().then(body => {
        caches.open(GAME_DATA_ENDPOINT).then(function(cache) {
          cache.put(GAME_DATA_ENDPOINT, new Response(JSON.stringify(body)));
        });
      }); 
      return new Response('{}');
    } else {
      /* Read data from cache */
      event.respondWith(
        caches.open(GAME_DATA_ENDPOINT).then(function(cache) {
          return cache.match(GAME_DATA_ENDPOINT).then(function (response) {
            return response || new Response('{}');;
          }) || new Response('{}');
          })
      );
    }
  }

  /* Cookie consent */ 
  if (url.match(COOKIE_CONSENT_ENDPOINT)) {
    if (method === 'POST') {
      /* Write data to cookie */
      request.json().then(body => {
        caches.open(COOKIE_CONSENT_ENDPOINT).then(function(cache) {
          cache.put(COOKIE_CONSENT_ENDPOINT, new Response(JSON.stringify(body)));
        });
      }); 
      return new Response('{}');
    } else {
      /* Read data from cookie */
      event.respondWith(
        caches.open(COOKIE_CONSENT_ENDPOINT).then(function(cache) {
          return cache.match(COOKIE_CONSENT_ENDPOINT).then(function (response) {
            return response || new Response('{}');;
          }) || new Response('{}');
        })
      );
    }
  }
});

/* All other requests */
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);

1 Ответ

0 голосов
/ 29 мая 2020

Я понял это!

Мне пришлось добавить matchOptions к стратегии CacheFirst в моем registerRoute:

workbox.routing.registerRoute(
  ({url}) => url.pathname.endsWith('.mp3'),
  new workbox.strategies.CacheFirst({
    cacheName: workbox.core.cacheNames.precache,
    plugins: [     
        new workbox.cacheableResponse.Plugin({ statuses: [200] }),
        new workbox.rangeRequests.Plugin(),
      ],
    matchOptions: {
      ignoreSearch: true,
      ignoreVary: true
    }
  })
);

Это могло быть связано с использованием Firebase для хостинга, но я не уверен.

...