Certains navigateurs traitent les requêtes d'éléments multimédias (c'est-à-dire l'URL spécifiée dans l'attribut src
des éléments <video>
et <audio>
) qui peut entraîner un comportement de diffusion incorrect, sauf si vous suivez des étapes spécifiques lors de la configuration de Workbox.
Problème
Les subtilités des navigateurs problématiques concernant la diffusion d'éléments audio et vidéo sont expliquées en détail dans cette discussion sur GitHub. La vue d'ensemble est complexe, mais voici les points clés à retenir:
- Vous devez indiquer à la boîte de travail de respecter les en-têtes de requête
Range
en utilisant le moduleworkbox-range-requests
pour la stratégie utilisée en tant que gestionnaire. - Les éléments
<video>
ou<audio>
doivent être activés en mode CORS avec l'attributcrossorigin
. - Si vous souhaitez diffuser du contenu multimédia à partir du cache, vous devez l'ajouter explicitement au cache à l'avance. Pour ce faire, vous pouvez effectuer une mise en cache préalable, utiliser
cache.add()
, ou encore utiliser la méthode "heatStrategyCache" dans des recettes de boîte de travail. La mise en cache de l'élément multimédia lors de sa diffusion au moment de l'exécution ne fonctionne pas, car seule une partie du contenu est extraite du réseau pendant la lecture.
Voici comment respecter ces exigences dans Workbox, en commençant par le balisage approprié d'un élément multimédia:
<!-- 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>
Ensuite, dans votre service worker, utilisez le plug-in workbox-range-request
pour gérer les éléments multimédias en conséquence:
// 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(),
],
}),
);
Cette approche vous permet de vous assurer que les éléments multimédias de votre site Web sont correctement récupérés et mis en cache par votre service worker, tout en prenant en compte les demandes de plages et les autres pièges éventuels liés aux demandes de médias.