Niektóre przeglądarki obsługują żądania zasobów multimedialnych, np. adres URL określony w atrybucie src
elementów <video>
i <audio>
, co może powodować nieprawidłowe wyświetlanie, jeśli nie wykonasz odpowiednich czynności podczas konfigurowania aplikacji Workbox.
Problem
Szczegóły problemów, z którymi borykają się przeglądarki związane z wyświetlaniem zasobów audio i wideo, zostały szczegółowo opisane w tym omówieniu problemu na GitHubie. Pełny obraz jest skomplikowany, ale najważniejsze kwestie to:
- Moduł roboczy musi przestrzegać nagłówków żądania
Range
, jeśli korzystasz z modułuworkbox-range-requests
w strategii używanej jako moduł obsługi. - Elementy
<video>
lub<audio>
muszą włączyć tryb CORS za pomocą atrybutucrossorigin
. - Jeśli chcesz wyświetlać multimedia z pamięci podręcznej, musisz wcześniej je do niej dodać. Możesz to zrobić za pomocą wstępnego buforowania lub za pomocą metody
cache.add()
albo metody WarmstrategiiCache w przepisach dotyczących pól roboczych. Zapisywanie zasobu multimedialnego w pamięci podręcznej podczas jego przesyłania strumieniowego nie zadziała, ponieważ podczas odtwarzania z sieci zostaną pobrane tylko częściowe treści.
Oto jak spełnić te wymagania w Workbox, zaczynając od właściwych znaczników zasobu multimedialnego:
<!-- 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>
Następnie w skrypcie service worker użyj wtyczki workbox-range-request
, aby odpowiednio obsłużyć zasoby multimedialne:
// 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(),
],
}),
);
Takie podejście pozwala zapewnić prawidłowe pobieranie i buforowanie zasobów multimedialnych witryny przez skrypt service worker, uwzględniając żądania zakresów i inne potencjalne pułapki związane z żądaniami mediów.