Menangani permintaan rentang dalam pekerja layanan

Pastikan pekerja layanan Anda tahu apa yang harus dilakukan saat respons sebagian diminta.

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

Service worker adalah kode JavaScript yang berada di antara aplikasi web dan jaringan, yang berpotensi mencegat permintaan jaringan keluar dan menghasilkan respons untuknya.

Secara historis, permintaan rentang dan pekerja layanan tidak berfungsi dengan baik. Anda perlu melakukan langkah-langkah khusus untuk menghindari hasil yang buruk di pekerja layanan Anda. Untungnya, hal ini mulai berubah. Di browser yang menunjukkan perilaku yang benar, permintaan rentang akan "langsung berfungsi" saat diteruskan melalui 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 dihapus 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 keberadaan header Range: secara eksplisit, dan tidak memanggil event.respondWith() jika ada. Dengan melakukan hal ini, pekerja layanan secara efektif menghapus dirinya sendiri dari gambar pembuatan respons, dan logika jaringan browser default, yang mengetahui cara mempertahankan permintaan rentang, akan digunakan.

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, sebagian besar developer tidak menyadari perlunya melakukan hal ini. Selain itu, alasan mengapa hal tersebut diperlukan tidak jelas. Pada akhirnya, batasan ini disebabkan oleh browser yang perlu mengikuti 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 mendapatkan 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, mulai dari versi 87, juga berperilaku dengan benar.

Per Oktober 2020 ini, Firefox belum memperbaiki perilaku ini, sehingga Anda mungkin masih perlu memperhitungkannya saat men-deploy kode pekerja layanan ke produksi.

Memeriksa baris "Sertakan header rentang dalam permintaan jaringan" di dasbor Pengujian Platform Web adalah cara terbaik untuk mengonfirmasi apakah browser tertentu telah memperbaiki perilaku ini atau tidak.

Bagaimana dengan permintaan rentang penayangan 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 dapat memenuhi permintaan dari cache tersebut, sehingga mengabaikan 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. Kode pekerja layanan untuk mengurai header Range: dengan benar dan hanya menampilkan segmen yang sesuai dari respons lengkap yang di-cache bukanlah hal yang mudah.

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

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