В определенных ситуациях вам может потребоваться кэширование резервного ответа на случай, если пользователь находится в автономном режиме. Реализация резервного варианта является альтернативой поведению кэширования, которое обеспечивают такие стратегии, как «сначала сеть» или «устаревание при повторной проверке».
Резервный вариант — это общий, универсальный ответ, который является лучшим заполнителем, чем тот, который браузер предоставляет по умолчанию в случае сбоя запроса. Некоторые примеры:
- Альтернатива заполнителю «отсутствующее изображение».
- Альтернатива HTML стандартной странице «Нет сетевого подключения».
Только офлайн-страница
Если все, что вам нужно сделать, это предоставить собственную автономную HTML-страницу и ничего больше, вот базовый рецепт, которому вы можете следовать:
import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';
setDefaultHandler(new NetworkOnly());
offlineFallback();
В приведенном выше коде используется setDefaultHandler
для использования стратегии только для сети в качестве стратегии по умолчанию для всех маршрутов. Затем он запускает рецепт offlineFallback
, чтобы обеспечить резервный режим в автономном режиме в случае возникновения ошибки. В рецепте предполагается, что резервный HTML-файл для автономного режима будет называться offline.html
и обслуживаться из корня вашего веб-сервера.
Комплексные резервные варианты
Всякий раз, когда происходит сбой в сети или промах кэша, стратегии кэширования, предлагаемые workbox-strategies
будут последовательно отклоняться. Это способствует шаблону установки глобального обработчика «catch» для обработки любых сбоев в одной функции-обработчике, что позволяет предлагать разные резервные варианты для разных значений request.destination
.
В следующем примере используется рецепт warmStrategyCache
из workbox-recipes
и устанавливается обработчик catch для обслуживания элементов, заранее кэшированных в кэше времени выполнения. Однако резервные варианты предварительного кэширования могут лучше подойти для вашего приложения:
import {warmStrategyCache} from 'workbox-recipes';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {CacheFirst, StaleWhileRevalidate} from 'workbox-strategies';
// Fallback assets to cache
const FALLBACK_HTML_URL = '/offline.html';
const FALLBACK_IMAGE_URL = '/images/image-not-found.jpg';
const FALLBACK_STRATEGY = new CacheFirst();
// Warm the runtime cache with a list of asset URLs
warmStrategyCache({
urls: [FALLBACK_HTML_URL, FALLBACK_IMAGE_URL],
strategy: FALLBACK_STRATEGY,
});
// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());
// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
// The warmStrategyCache recipe is used to add the fallback assets ahead of
// time to the runtime cache, and are served in the event of an error below.
// Use `event`, `request`, and `url` to figure out how to respond, or
// use request.destination to match requests for specific resource types.
switch (request.destination) {
case 'document':
return FALLBACK_STRATEGY.handle({event, request: FALLBACK_HTML_URL});
case 'image':
return FALLBACK_STRATEGY.handle({event, request: FALLBACK_IMAGE_URL});
default:
// If we don't have a fallback, return an error response.
return Response.error();
}
});
Далее резервные ответы предварительно кэшируются с помощью injectManifest
с помощью инструментов сборки Workbox и служат резервным вариантом в случае ошибки с помощью метода matchPrecache
.
import {matchPrecache, precacheAndRoute} from 'workbox-precaching';
import {setDefaultHandler, setCatchHandler} from 'workbox-routing';
import {StaleWhileRevalidate} from 'workbox-strategies';
// Optional: use the injectManifest mode of one of the Workbox
// build tools to precache a list of URLs, including fallbacks.
precacheAndRoute(self.__WB_MANIFEST);
// Use a stale-while-revalidate strategy to handle requests by default.
setDefaultHandler(new StaleWhileRevalidate());
// This "catch" handler is triggered when any of the other routes fail to
// generate a response.
setCatchHandler(async ({request}) => {
// Fallback assets are precached when the service worker is installed, and are
// served in the event of an error below. Use `event`, `request`, and `url` to
// figure out how to respond, or use request.destination to match requests for
// specific resource types.
switch (request.destination) {
case 'document':
// FALLBACK_HTML_URL must be defined as a precached URL for this to work:
return matchPrecache(FALLBACK_HTML_URL);
case 'image':
// FALLBACK_IMAGE_URL must be defined as a precached URL for this to work:
return matchPrecache(FALLBACK_IMAGE_URL);
default:
// If we don't have a fallback, return an error response.
return Response.error();
}
});
Примером варианта использования второй резервной настройки является ситуация, когда страница была кэширована заранее, а изображения (или другие ресурсы), запрошенные страницей, — нет. Страница по-прежнему может быть прочитана из кэша, когда пользователь находится в автономном режиме, но могут быть предоставлены резервные заполнители или альтернативные функции в случае возникновения сетевой ошибки.
Потепление кэша времени выполнения
Workbox поддерживает отдельные кэши для предварительного кэширования и кэша времени выполнения, и могут возникнуть ситуации, когда вы захотите кэшировать что-то заранее, не полагаясь на предварительное кэширование, поскольку обновления манифеста предварительного кэширования потребуют от вас развертывания обновленного сервисного работника.
Чтобы заранее заполнить кэш среды выполнения активами, вы можете использовать рецепт warmStrategyCache
из workbox-recipes
. Под капотом эта стратегия вызывает Cache.addAll
в событии install
сервис-воркера.
import {warmStrategyCache} from 'workbox-recipes';
import {CacheFirst} from 'workbox-strategies';
// This can be any strategy, CacheFirst used as an example.
const strategy = new CacheFirst();
const urls = [
'/offline.html',
];
warmStrategyCache({urls, strategy});
Заключение
Управление резервными ответами на неудачные запросы требует некоторой работы, но при небольшом предварительном планировании вы можете настроить свое веб-приложение так, чтобы оно предоставляло определенный уровень контента и функциональности, когда пользователь находится в автономном режиме.