Zarządzanie odpowiedziami zastępczymi

W niektórych sytuacjach możesz chcieć umieścić odpowiedź zastępczą w pamięci podręcznej, na wypadek gdyby użytkownik był offline. Implementacja kreacji zastępczych to alternatywa dla buforowania, z którego korzystają strategie takie jak ukierunkowanie na sieć lub brak aktualizacji w trakcie ponownej walidacji.

Kreacja zastępcza to ogólna, elastyczna odpowiedź, która jest lepszym obiektem zastępczym niż ta, którą przeglądarka dostarczy domyślnie w przypadku niepowodzenia żądania. Na przykład:

  • Alternatywa dla obiektu zastępczego „brakujący obraz”.
  • Kod HTML alternatywny dla standardowej strony „Brak dostępnego połączenia sieciowego”.

Tylko strona offline

Jeśli musisz tylko udostępnić niestandardową stronę HTML offline, możesz skorzystać z tego podstawowego przepisu:

import {offlineFallback} from 'workbox-recipes';
import {setDefaultHandler} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

setDefaultHandler(new NetworkOnly());

offlineFallback();

Powyższy kod używa zdarzenia setDefaultHandler, aby używać strategii obejmującej tylko sieć jako domyślnej dla wszystkich tras. Następnie uruchamia przepis offlineFallback, aby wyświetlić zastępczą konfigurację offline w przypadku wystąpienia błędu. W przepisie założono, że plik HTML kreacji zastępczej offline będzie miał nazwę offline.html i będzie wyświetlany z poziomu katalogu głównego serwera WWW.

Kompleksowe wartości zastępcze

Przy każdej awarii sieci lub braku w pamięci podręcznej strategie buforowania oferowane przez workbox-strategies są konsekwentnie odrzucane. Powoduje to promowanie wzorca ustawiania globalnego modułu obsługi typu „catch” do obsługi wszelkich błędów w pojedynczej funkcji modułu, co umożliwia oferowanie różnych wartości zastępczych dla różnych wartości request.destination.

W poniższym przykładzie używamy przepisu warmStrategyCache z workbox-recipes i ustawiamy moduł obsługi przechwytywania, aby wyświetlać elementy zapisane w pamięci podręcznej z wyprzedzeniem. W przypadku Twojej aplikacji lepszym rozwiązaniem może być jednak wstępne zapisywanie reklam zastępczych:

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();
  }
});

W kolejnym przykładzie odpowiedzi zastępcze są wstępnie zapisywane w pamięci podręcznej za pomocą injectManifest z narzędziami kompilacji Workbox i służą jako kreacja zastępcza w przypadku błędu metody 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();
  }
});

Przykładowe zastosowanie drugiej konfiguracji kreacji zastępczej dotyczy sytuacji, w której strona była przechowywana w pamięci podręcznej z wyprzedzeniem, ale nie ma w niej obrazów (lub innych zasobów), których żądała. Gdy użytkownik jest offline, stronę można nadal odczytywać z pamięci podręcznej, ale w przypadku błędu sieci mogą być dostępne zastępcze lub alternatywne funkcje.

Przygotowywanie pamięci podręcznej środowiska wykonawczego

Skrzynka robocza przechowuje osobne pamięci podręcznej na potrzeby wstępnego buforowania i pamięci podręcznej. Może się też zdarzyć, że zechcesz zapisać coś z wyprzedzeniem bez konieczności wstępnego buforowania, ponieważ aktualizacje pliku manifestu precache będą wymagały wdrożenia zaktualizowanego skryptu service worker.

Aby z wyprzedzeniem zapełnić pamięć podręczną środowiska wykonawczego za pomocą zasobów, możesz skorzystać z przepisu warmStrategyCache z workbox-recipes. Ta strategia wywołuje metodę Cache.addAll w zdarzeniu install skryptu service worker.

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});

Podsumowanie

Zarządzanie odpowiedziami zastępczymi dla nieudanych żądań zajmuje trochę czasu, ale po odrobinie planowania z wyprzedzeniem możesz tak skonfigurować aplikację internetową, by udostępniała pewne treści i funkcje, gdy użytkownik jest offline.