מציג וידאו ואודיו שנשמרו במטמון

יש כמה קמטים באופן שבו דפדפנים מסוימים מטפלים בבקשות לנכסי מדיה — כלומר כתובת ה-URL שצוינה במאפיין src של הרכיבים <video> ו-<audio> — ועלולה לגרום להתנהגות שגויה של הצגת המודעות, אלא אם מבצעים פעולות ספציפיות בזמן הגדרת תיבת עבודה.

הבעיה

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

  • צריך להגדיר לתיבת העבודה לכבד את כותרות הבקשות של Range באמצעות המודול workbox-range-requests לאסטרטגיה שמשמשת כ-handler.
  • רכיבי <video> או <audio> צריכים להצטרף למצב CORS עם המאפיין crossorigin.
  • אם רוצים להציג מדיה מהמטמון, צריך להוסיף אותה מראש למטמון באופן מפורש. אפשר לעשות זאת באמצעות שמירה מראש במטמון, או באמצעות cache.add() או באמצעות המתודה hotStrategyמטמון ב-workbox-recipes. אי אפשר לשמור נכס מדיה במטמון בזמן שהוא משודר בזמן ריצה, כי רק תוכן חלקי מאוחזר מהרשת במהלך ההפעלה.

כדי להתאים לדרישות האלה ב-Workbox, מתחילים בתגי העיצוב הנכונים של נכס מדיה:

<!-- In your page: -->

<!-- You need to set `crossorigin`, even for same-origin URLs! -->
<video src="movie.mp4" crossorigin="anonymous"></video>
<audio src="song.mp3" crossorigin="anonymous"></audio>

לאחר מכן ב-Service Worker, משתמשים בפלאגין workbox-range-request כדי לטפל בנכסי המדיה בהתאם:

// sw.js
import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponsePlugin} from 'workbox-cacheable-response';
import {RangeRequestsPlugin} from 'workbox-range-requests';

// In your service worker:
// It's up to you to either precache, use warmRuntimeCache, or
// explicitly call cache.add() to populate the cache with media assets.
// If you choose to cache media assets up front, do so with care,
// as they can be quite large and exceed storage quotas.
//
// This route will go to the network if there isn't a cache match,
// but it won't populate the cache at runtime because the response for
// the media asset will be a partial 206 response. If there is a cache
// match, then it will properly serve partial responses.
registerRoute(
  ({request}) => {
    const {destination} = request;

    return destination === 'video' || destination === 'audio'
  },
  new CacheFirst({
    cacheName: 'your-cache-name-here',
    plugins: [
      new CacheableResponsePlugin({
        statuses: [200]
      }),
      new RangeRequestsPlugin(),
    ],
  }),
);

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