Existen algunas diferencias en la forma en que algunos navegadores manejan las solicitudes de elementos multimedia (es decir, la URL especificada en el atributo src
de los elementos <video>
y <audio>
), lo que puede generar un comportamiento de publicación incorrecto, a menos que tomes pasos específicos al configurar Workbox.
El problema
Las particularidades del problema que tienen los navegadores en cuanto a la entrega de elementos de audio y video se explican en detalle en este debate sobre un problema en GitHub. El panorama completo es complicado, pero los puntos clave son los siguientes:
- Se debe solicitar al equipo de trabajo que respete los encabezados de solicitud
Range
mediante el móduloworkbox-range-requests
para la estrategia utilizada como controlador. - Los elementos
<video>
o<audio>
deben habilitar el modo CORS con el atributocrossorigin
. - Si quieres entregar medios desde la caché, debes agregarlo explícitamente a la caché con anticipación. Puedes hacerlo mediante el almacenamiento previo en caché, con
cache.add()
o con el método cleanStrategyCache en workbox-recipes. El almacenamiento en caché del elemento multimedia mientras se transmite en el tiempo de ejecución no funciona, ya que solo se recupera contenido parcial de la red durante la reproducción.
Aquí te mostramos cómo cumplir con estos requisitos en Workbox comenzando con el lenguaje de marcado adecuado para un recurso multimedia:
<!-- 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>
Luego, en tu service worker, usa el complemento workbox-range-request
para controlar los elementos multimedia según corresponda:
// 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 este enfoque, puedes asegurarte de que tu service worker recupere y almacene en caché los recursos multimedia de tu sitio web, a la vez que se tienen en cuenta las solicitudes de rango y otras posibles dificultades relacionadas con las solicitudes de medios.