302 редиректы не работают в сервис-воркере, созданном с помощью Google Workbox

Для отображения предупреждения «добавить фолиант на главный экран» я хочу интегрировать сервис-воркера и автономную возможность приложения: когда пользователь находится в автономном режиме, приложение должно просто отображать специальный автономный HTML-файл.

Мой сервис-воркер выглядит так:

importScripts('https://storage.googleapis.com/workbox-cdn/releases/3.1.0/workbox-sw.js');

const CACHE_VERSION = 1;

workbox.core.setCacheNameDetails({
  prefix: 'app',
  suffix: 'v' + CACHE_VERSION
});

workbox.routing.registerRoute(
    '/offline-page.html',
    workbox.strategies.networkFirst({
        networkTimeoutSeconds: 2,
        cacheableResponse: { statuses: [0, 200] },
    })
)

workbox.routing.registerRoute(
    ({ event }) => event.request.mode === 'navigate',
    ({ url }) =>
        fetch(url.href, { credentials: 'include', redirect: 'follow', }).catch(() => caches.match('/offline-page.html'))
)

Но как только мое приложение возвращает перенаправление 302 (например, после входа в систему или выхода из системы), я получаю следующее предупреждающее сообщение в консоли:

Событие FetchEvent для «https://app.com» привело к ответу с сетевой ошибкой: для запрос, режим перенаправления которого не является "отслеживаемым".

а Google Chrome отображает страницу с ошибкой (ERR_FAILED), в которой говорится, что веб-сайт недоступен.

Есть у кого-нибудь идеи, как это исправить?


person Tineler    schedule 28.04.2018    source источник


Ответы (2)


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

Для этого есть несколько различных вариантов, но самым простым было бы создание собственного стратегия только для сети (чтобы имитировать fetch(), который вы используете в своем примере), присоедините .catch() к его концу, а затем используйте это как handler при построении NavigationRoute.

Это даст вам Route, который затем можно передать на _ 6_.

// You're responsible for either precaching or
// explicitly adding OFFLINE_HTML to one of the caches.
const OFFLINE_HTML = '/offline-page.html';
const networkOnly = workbox.strategies.networkOnly();
const networkOnlyWithFallback = networkOnly().catch(() => caches.match(OFFLINE_HTML));
const route = new workbox.routing.NavigationRoute(networkOnlyWithFallback);
workbox.routing.registerRoute(route);
person Jeff Posnick    schedule 30.04.2018
comment
Если я использую ваш код, я получаю следующую ошибку: Uncaught TypeError: networkOnly.catch is not a function. Также прямо сейчас я делаю именно то, что вы разместили здесь: GitHub Issue. Просто 302 редиректа некорректно обрабатывает мой сервис-воркер ... - person Tineler; 04.05.2018

Кажется, это помогает:

const FALLBACK_URL = '/';

const networkOnly = workbox.strategies.networkOnly();

const route = new workbox.routing.NavigationRoute(({event}) => {
  return networkOnly.handle({event})
    .catch(() => caches.match(FALLBACK_URL));
});

workbox.routing.registerRoute(route);
person Patrik Beck    schedule 23.11.2018
comment
Для Workbox версии 4.3.1 используйте: const FALLBACK_URL = workbox.precaching.getCacheKeyForURL('/offline.html'); workbox.routing.registerRoute( new workbox.routing.NavigationRoute(({event}) => { return (new workbox.strategies.NetworkOnly()).handle({event}) .catch(() => caches.match(FALLBACK_URL)); }) ); - person August Jelemson; 04.08.2019