ניהול התשובות החלופיות

במצבים מסוימים, כדאי לשמור במטמון תגובה חלופית למקרה שהמשתמש לא מחובר לאינטרנט. הטמעה של חלופה היא חלופה להתנהגויות של שמירה במטמון, שמספקות אסטרטגיות כמו 'מתן עדיפות לרשת' או 'לא פעיל בזמן אימות מחדש'.

חלופה היא תשובה כללית שמתאימה לכולם, שהיא placeholder טוב יותר מאשר מה שהדפדפן היה מספק כברירת מחדל כשבקשה נכשלת. לפניכם מספר דוגמאות:

  • חלופה ל'תמונה חסרה' placeholder.
  • חלופה ל-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 והוא יוצג מהרמה הבסיסית (root) של שרת האינטרנט שלך.

חלופות מקיפות

בכל פעם שמתרחש כשל ברשת או שגיאה במטמון, אסטרטגיות השמירה במטמון שמוצעות על ידי workbox-strategies יידחו באופן עקבי. זה מקדם את הדפוס של הגדרה של "catch" גלובלי handler לטיפול בכשלים בפונקציית handler בודדת, שמאפשרת להציע חלופות שונות לערכי request.destination שונים.

הדוגמה הבאה משתמשת במתכון של warmStrategyCache מ-workbox-recipes ומגדירה handler של קליטה כדי להציג פריטים שנשמרו מראש במטמון של סביבת זמן הריצה. עם זאת, יכול להיות שחלופות חלופיות לשמירה במטמון יכולות להתאים יותר לאפליקציה שלכם:

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 עם כלי ה-build של 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();
  }
});

תרחיש לדוגמה של הגדרה חלופית שנייה: אם דף מסוים נשמר במטמון מראש, אבל תמונות (או נכסים אחרים) שהתבקשו על ידי הדף לא נשמרו. עדיין אפשר לקרוא את הדף מהמטמון כשהמשתמש במצב אופליין, אבל אפשר לספק placeholders חלופיים או פונקציונליות חלופית במקרה של שגיאה ברשת.

הפעלת המטמון של סביבת זמן הריצה

תיבת העבודה שומרת מטמון נפרד לשמירה במטמון ולמטמון זמן ריצה, ויכול להיות שיהיו מצבים שבהם תרצו לשמור משהו במטמון מראש בלי להסתמך על שמירה מראש, כי עדכונים למניפסט של המטמון מראש ידרשו מכם לפרוס קובץ שירות (service worker) מעודכן.

כדי לתכנת מראש את המטמון של סביבת זמן הריצה באמצעות נכסים, אפשר להשתמש במתכון של warmStrategyCache מ-workbox-recipes. כשמפעילים את התכונה הזו, המערכת קוראת לשיטה Cache.addAll באירוע install של קובץ שירות (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});

סיכום

ניהול התגובות החלופיות לבקשות שנכשלו לוקח קצת זמן, אבל עם קצת תכנון מראש אפשר להגדיר שאפליקציית האינטרנט תספק רמה מסוימת של תוכן ופונקציונליות כשהמשתמש לא מחובר לאינטרנט.