วิธีที่บางเบราว์เซอร์จัดการคำขอเนื้อหาสื่อมีริ้วรอยบางอย่าง กล่าวคือ URL ที่ระบุในแอตทริบิวต์ src
ขององค์ประกอบ <video>
และ <audio>
อาจทำให้เกิดลักษณะการแสดงผลที่ไม่ถูกต้อง เว้นแต่คุณจะทำตามขั้นตอนเฉพาะเมื่อกำหนดค่า Workbox
ปัญหา
คำอธิบายอย่างละเอียดของปัญหาที่เบราว์เซอร์เกี่ยวกับการแสดงเนื้อหาเสียงและวิดีโอได้รับการอธิบายอย่างละเอียดในการพูดคุยเกี่ยวกับปัญหาของ GitHub นี้ ภาพรวมทั้งหมดนั้นซับซ้อน แต่ประเด็นสำคัญมีดังนี้
- ต้องกำหนดให้ Workbox ทำตามส่วนหัวของคำขอ
Range
โดยใช้โมดูลworkbox-range-requests
กับกลยุทธ์ที่ใช้เป็นตัวแฮนเดิล - องค์ประกอบ
<video>
หรือ<audio>
ต้องเลือกใช้โหมด CORS ที่มีแอตทริบิวต์crossorigin
- หากคุณต้องการแสดงสื่อจากแคช คุณควรเพิ่มสื่อนั้นลงในแคชอย่างชัดเจนล่วงหน้า ซึ่งทำได้โดยการแคชล่วงหน้าหรือด้วย
cache.add()
หรือใช้เมธอด WarmStrategyCache ในสูตรอาหารกล่องงาน การแคชเนื้อหาสื่อขณะที่สตรีมระหว่างรันไทม์จะไม่ทำงาน เนื่องจากระบบจะดึงเนื้อหาเพียงบางส่วนจากเครือข่ายระหว่างการเล่น
วิธีปฏิบัติตามข้อกำหนดเหล่านี้ใน 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>
จากนั้นในโปรแกรมทำงานของบริการ ให้ใช้ปลั๊กอิน 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 อย่างเหมาะสม ในขณะเดียวกันก็คำนึงถึงคำขอช่วงและข้อผิดพลาดอื่นๆ ที่อาจเกิดขึ้นซึ่งเกี่ยวข้องกับคำขอสื่อด้วย