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

יש כמה קמטים באופן שבו דפדפנים מסוימים מטפלים בבקשות לנכסי מדיה — כלומר כתובת ה-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, תוך התייחסות לבקשות לטווח ולמכשולים אפשריים אחרים שקשורים לבקשות מדיה.