Il modo in cui alcuni browser gestiscono le richieste di asset multimediali, ovvero l'URL specificato nell'attributo src
degli elementi <video>
e <audio>
, presenta alcune incomprensioni, che possono portare a un comportamento di pubblicazione non corretto, a meno che non vengano eseguiti passaggi specifici durante la configurazione di Workbox.
Il problema
Le complessità dei problemi riscontrati dai browser in relazione alla pubblicazione di asset audio e video sono spiegate in dettaglio in questa discussione su GitHub. Il quadro completo è complicato, ma i punti chiave sono:
- Alla casella di lavoro deve essere richiesto di rispettare le intestazioni delle richieste
Range
utilizzando il moduloworkbox-range-requests
con la strategia utilizzata come gestore. - Gli elementi
<video>
o<audio>
devono attivare la modalità CORS con l'attributocrossorigin
. - Se vuoi pubblicare contenuti multimediali dalla cache, devi aggiungerli esplicitamente in anticipo alla cache. Puoi farlo tramite la pre-memorizzazione nella cache, con
cache.add()
oppure utilizzando il metodo hotStrategyCache nelle formule di workbox. La memorizzazione nella cache dell'asset multimediale durante la riproduzione in streaming in fase di runtime non funzionerà, poiché durante la riproduzione vengono recuperati solo contenuti parziali dalla rete.
Di seguito viene spiegato come soddisfare questi requisiti in Workbox, iniziando con il markup appropriato per un asset multimediale:
<!-- 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>
Quindi, nel tuo service worker, utilizza il plug-in workbox-range-request
per gestire gli asset multimediali di conseguenza:
// 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(),
],
}),
);
Con questo approccio, puoi garantire che le risorse multimediali del tuo sito web vengano recuperate e memorizzate correttamente nella cache dal tuo service worker, tenendo in considerazione le richieste di intervallo e altre potenziali insidie legate alle richieste multimediali.