Menangani permintaan rentang dalam pekerja layanan

Pastikan pekerja layanan Anda tahu apa yang harus dilakukan ketika respons parsial diminta.

Beberapa permintaan HTTP berisi header Range:, yang menunjukkan bahwa hanya sebagian dari resource lengkap yang harus ditampilkan. Layanan ini biasanya digunakan untuk streaming konten audio atau video agar potongan media yang lebih kecil dapat dimuat sesuai permintaan, alih-alih meminta keseluruhan file jarak jauh sekaligus.

Pekerja layanan adalah kode JavaScript yang berada di antara aplikasi web dan jaringan, yang berpotensi mencegat permintaan jaringan keluar dan menghasilkan respons untuk permintaan tersebut.

Secara historis, permintaan rentang dan pekerja layanan tidak berjalan dengan baik. Anda perlu melakukan langkah khusus untuk menghindari hasil yang buruk pada pekerja layanan 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 yang 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 dihapus secara otomatis. Permintaan yang diterima oleh server jarak jauh tidak akan menyertakan Range: sama sekali. Tindakan ini tidak selalu "merusak" apa pun, karena server secara teknis diizinkan untuk menampilkan isi respons lengkap, dengan kode status 200, bahkan jika header Range: ada dalam permintaan asli. Namun, cara ini akan mengakibatkan lebih banyak data yang ditransfer daripada yang benar-benar diperlukan dari perspektif browser.

Developer yang mengetahui perilaku ini dapat mengatasinya dengan memeriksa keberadaan header Range: secara eksplisit, dan tidak memanggil event.respondWith() jika header tersebut ada. Dengan melakukan ini, pekerja layanan secara efektif menghapus dirinya sendiri dari gambar pembuatan respons, dan logika jaringan browser default, yang mengetahui cara mempertahankan permintaan rentang, 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. Tidak jelas mengapa hal itu diperlukan. Pada akhirnya, batasan ini disebabkan oleh browser perlu mengejar perubahan dalam spesifikasi yang mendasarinya, yang menambahkan dukungan untuk fungsi ini.

Apa saja yang telah diperbaiki?

Browser yang berperilaku dengan benar akan mempertahankan header Range: saat event.request diteruskan ke fetch(). Ini berarti kode pekerja layanan dalam contoh awal saya akan memungkinkan server jarak jauh melihat header Range:, jika disetel oleh browser:

self.addEventListener('fetch', (event) => {
  // The Range: header will pass through in browsers
  // that behave correctly.
  event.respondWith(fetch(event.request));
});

Sekarang server memiliki kesempatan untuk menangani permintaan rentang dengan benar dan menampilkan respons sebagian dengan kode status 206.

Browser mana yang berperilaku dengan benar?

Safari versi terbaru memiliki fungsi yang benar. Chrome dan Edge, dimulai dari versi 87, juga berperilaku dengan benar.

Sejak Oktober 2020 ini, Firefox belum memperbaiki perilaku ini, jadi Anda mungkin masih harus 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 melayani permintaan rentang dari cache?

Pekerja layanan dapat melakukan lebih dari sekadar meneruskan permintaan ke jaringan. Kasus penggunaan yang umum adalah menambahkan resource, seperti file audio dan video, ke cache lokal. Pekerja layanan kemudian bisa memenuhi permintaan dari cache tersebut, dengan melewati jaringan sepenuhnya.

Semua browser, termasuk Firefox, mendukung pemeriksaan permintaan di dalam pengendali fetch, memeriksa keberadaan header Range:, lalu memenuhi permintaan secara lokal dengan respons 206 yang berasal dari cache. Namun, kode pekerja layanan untuk mengurai header Range: dengan benar dan hanya menampilkan segmen yang sesuai dari respons lengkap yang di-cache tidaklah mudah.

Untungnya, developer yang menginginkan bantuan dapat menggunakan Workbox, yang merupakan serangkaian library yang menyederhanakan kasus penggunaan pekerja layanan umum. workbox-range-request module mengimplementasikan semua logika yang diperlukan untuk memberikan respons parsial langsung dari cache. Resep lengkap untuk kasus penggunaan ini dapat ditemukan di dokumentasi Workbox.

Banner besar di postingan ini adalah Natalie Rhea Riggs di Unsplash.