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. 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 mengambil 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 "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 berarti "merusak" apa pun, karena server secara teknis diizinkan untuk menampilkan isi respons lengkap, dengan kode status 200, meskipun ada header Range: dalam permintaan aslinya. Namun, hal itu akan mengakibatkan lebih banyak data yang ditransfer melebihi yang sebenarnya 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 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 pentingnya melakukan hal ini. Selain itu, alasan mengapa hal tersebut diperlukan tidak jelas. Pada akhirnya, keterbatasan ini terjadi karena browser perlu mengikuti perubahan spesifikasi dasar, 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 mengizinkan server jarak jauh untuk 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));
});

Server kini mendapat 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.

Sejak Oktober 2020, 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" pada dasbor Web Platform Tests adalah cara terbaik untuk mengonfirmasi apakah browser tertentu telah memperbaiki perilaku ini atau belum.

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 tidaklah 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.

Gambar hero di postingan ini adalah karya Natalie Rhea Riggs di Unsplash.