Dipublikasikan: 6 Oktober 2020
Beberapa permintaan HTTP berisi header Range:, yang menunjukkan bahwa hanya sebagian dari resource lengkap yang harus ditampilkan. Rentang byte umumnya digunakan untuk melakukan streaming konten audio atau video agar potongan media yang lebih kecil dapat dimuat sesuai permintaan, bukan meminta seluruh file jarak jauh sekaligus.
Pekerja layanan adalah kode JavaScript yang berada di antara aplikasi web dan jaringan, yang berpotensi mencegat permintaan jaringan keluar dan membuat respons untuk permintaan tersebut.
Sebelumnya, permintaan rentang dan pekerja layanan tidak dapat bekerja sama dengan baik. Anda perlu melakukan langkah-langkah khusus untuk menghindari hasil yang buruk di service worker Anda. Untungnya, hal ini mulai berubah. Di browser yang menunjukkan perilaku yang benar, permintaan rentang akan "berfungsi" saat melewati pekerja layanan.
Apa masalahnya?
Pertimbangkan pekerja layanan dengan pemroses peristiwa fetch berikut, yang mengambil setiap permintaan masuk dan meneruskannya ke jaringan:
self.addEventListener('fetch', (event) => {
// The Range: header will not pass through in
// browsers that behave incorrectly.
event.respondWith(fetch(event.request));
});
Di browser dengan perilaku yang salah, jika event.request menyertakan header Range:, header tersebut akan dihilangkan secara diam-diam. Permintaan yang diterima oleh server jarak jauh tidak akan menyertakan Range: sama sekali. Hal ini tidak akan "merusak" apa pun, karena server secara teknis diizinkan untuk menampilkan isi respons lengkap, dengan kode status 200, meskipun header Range: ada dalam permintaan asli. Namun, hal ini akan menyebabkan lebih banyak data yang ditransfer daripada yang benar-benar diperlukan dari perspektif browser.
Developer yang mengetahui perilaku ini dapat mengatasinya dengan memeriksa secara eksplisit keberadaan header Range:, dan tidak memanggil event.respondWith() jika ada. Dengan melakukannya, pekerja layanan secara efektif menghapus dirinya sendiri dari gambar pembuatan respons, dan logika jaringan browser default, yang mengetahui cara mempertahankan permintaan rentang, akan digunakan sebagai gantinya.
self.addEventListener('fetch', (event) => {
// Return without calling event.respondWith()
// if this is a range request.
if (event.request.headers.has('range')) {
return;
}
event.respondWith(fetch(event.request));
});
Namun, dapat dikatakan bahwa sebagian besar developer tidak menyadari perlunya melakukan hal ini. Selain itu, alasan persyaratan tersebut tidak jelas. Pada akhirnya, batasan ini disebabkan oleh browser yang perlu menyesuaikan perubahan dalam spesifikasi yang mendasarinya, yang menambahkan dukungan untuk fungsi ini.
Apa yang telah diperbaiki?
Browser yang berperilaku dengan benar akan mempertahankan header Range: saat event.request diteruskan ke fetch(). Artinya, kode pekerja layanan dalam contoh awal saya akan memungkinkan server jarak jauh melihat header Range:, jika ditetapkan oleh browser:
self.addEventListener('fetch', (event) => {
// The Range: header will pass through in browsers
// that behave correctly.
event.respondWith(fetch(event.request));
});
Server kini memiliki kesempatan untuk menangani permintaan rentang dengan benar dan menampilkan respons sebagian dengan kode status 206.
Browser mana yang berperilaku dengan benar?
Versi terbaru Safari memiliki fungsi yang benar. Chrome dan Edge, mulai dari versi 87, juga berperilaku dengan benar.
Hingga Oktober 2020 ini, Firefox belum memperbaiki perilaku ini, jadi Anda mungkin masih perlu memperhitungkannya saat men-deploy kode pekerja layanan ke produksi.
Memeriksa baris "Include range header in network request" di dasbor Web Platform Tests adalah cara terbaik untuk mengonfirmasi apakah browser tertentu telah memperbaiki perilaku ini atau tidak.
Bagaimana dengan menyajikan permintaan rentang dari cache?
Pekerja layanan dapat melakukan lebih dari sekadar meneruskan permintaan ke jaringan. Kasus penggunaan umum adalah menambahkan resource, seperti file audio dan video, ke cache lokal. Kemudian, pekerja layanan dapat memenuhi permintaan dari cache tersebut, dengan sepenuhnya melewati jaringan.
Semua browser, termasuk Firefox, mendukung pemeriksaan permintaan di dalam handler fetch, memeriksa keberadaan header Range:, lalu memenuhi permintaan secara lokal dengan respons 206 yang berasal dari cache. Kode pekerja layanan untuk mengurai header Range: dengan benar dan hanya menampilkan segmen yang sesuai dari respons yang di-cache lengkap tidaklah mudah.
Untungnya, developer yang menginginkan bantuan dapat menggunakan Workbox, yang merupakan sekumpulan library yang menyederhanakan kasus penggunaan pekerja layanan umum. workbox-range-request module menerapkan semua logika yang diperlukan untuk menyajikan respons parsial langsung dari cache. Resep lengkap untuk kasus penggunaan ini dapat ditemukan dalam dokumentasi Workbox.