Service Worker'da aralık isteklerini işleme

Hizmet çalışanınızın, kısmi yanıt istendiğinde ne yapacağını bildiğinden emin olun.

Bazı HTTP isteklerinde, kaynağın yalnızca bir kısmının döndürülmesi gerektiğini belirten bir Range: üst bilgisi bulunur. Bunlar genellikle uzak dosyanın tamamını tek seferde istemek yerine daha küçük medya parçalarının isteğe bağlı olarak yüklenmesine olanak tanımak için ses veya video içeriği aktarırken kullanılır.

Hizmet çalışanı, web uygulamanız ile ağ arasında yer alan ve giden ağ isteklerini durdurup bunlar için yanıtlar oluşturabilen JavaScript kodudur.

Daha önce aralık istekleri ve hizmet çalışanları birlikte iyi çalışmadı. Hizmet çalışanınızda kötü sonuçlarla karşılaşmamak için özel adımlar atmanız gerekiyordu. Neyse ki bu durum değişmeye başlıyor. Doğru davranışı gösteren tarayıcılarda, aralık istekleri bir hizmet çalışanından geçerken "sadece çalışır".

Sorun nedir?

Aşağıdaki fetch etkinlik dinleyicisine sahip bir hizmet çalışanı düşünün. Bu dinleyici, gelen her isteği alıp ağa iletir:

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

Yanlış davranışa sahip tarayıcılarda, event.request bir Range: üst bilgisi içeriyorsa bu üst bilgi sessizce atlanır. Uzak sunucu tarafından alınan istekte Range: hiç yer almaz. Orijinal istekte Range: üstbilgisi olsa bile sunucunun teknik olarak 200 durum kodu ile tam yanıt gövdesini döndürmesine izin verildiğinden bu durum herhangi bir şeyi "bozmayacaktır". Ancak bu, tarayıcı açısından kesinlikle gerekli olandan daha fazla veri aktarılmasına neden olur.

Bu davranışın farkında olan geliştiriciler, Range: başlığının varlığını açıkça kontrol ederek ve varsa event.respondWith() işlevini çağırmadan bu sorunun üstesinden gelebilir. Bu işlemle hizmet çalışanı, kendisini yanıt oluşturma sürecinden etkili bir şekilde kaldırır ve bunun yerine aralık isteklerini nasıl koruyacağını bilen varsayılan tarayıcı ağ mantığı kullanılır.

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));
});

Ancak çoğu geliştiricinin bunu yapmanın gerekli olduğunun farkında olmadığını söyleyebiliriz. Ayrıca, bu işlemin neden zorunlu tutulması gerektiği açık değildi. Bu sınırlama, tarayıcıların bu işlev için destek ekleyen temel spesifikasyondaki değişikliklere ayak uydurması gerektiğinden kaynaklanıyordu.

Hangi sorunlar düzeltildi?

Doğru şekilde davranan tarayıcılar, event.request fetch()'ye iletildiğinde Range: üstbilgisini korur. Bu, ilk örneğimdeki hizmet çalışanı kodunun, tarayıcı tarafından ayarlanmışsa uzak sunucunun Range: üstbilgisini görmesine izin vereceği anlamına gelir:

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

Sunucu artık aralık isteğini düzgün şekilde işleme ve 206 durum kodu içeren kısmi bir yanıt döndürme şansı elde eder.

Hangi tarayıcılar doğru şekilde çalışır?

Safari'nin son sürümlerinde doğru işlevler bulunur. 87 sürümü ve sonraki sürümlerde Chrome ve Edge de doğru şekilde çalışır.

Ekim 2020 itibarıyla Firefox bu davranışı henüz düzeltmediğinden, hizmet çalışanınızın kodunu üretime dağıtırken bu durumu hesaba katmanız gerekebilir.

Belirli bir tarayıcının bu davranışı düzeltip düzeltmediğini onaylamak için en iyi yöntem, Web Platform Testleri kontrol panelindeki "Aralık başlığını ağ isteğine dahil et" satırını kontrol etmektir.

Aralık isteklerini önbellekten yayınlama ne olacak?

Hizmet çalışanları, isteği ağa iletmekten çok daha fazlasını yapabilir. Ses ve video dosyaları gibi kaynakları yerel önbelleğe eklemek yaygın bir kullanım alanıdır. Bir hizmet çalışanı, ağı tamamen atlayarak bu önbellekten gelen istekleri yerine getirebilir.

Firefox dahil tüm tarayıcılar, bir fetch işleyici içindeki isteği incelemeyi, Range: başlığının varlığını kontrol etmeyi ve ardından isteği yerel olarak bir önbellekten gelen 206 yanıtıyla karşılamayı destekler. Ancak Range: üst bilgisini doğru şekilde ayrıştıracak ve önbelleğe alınan yanıtın yalnızca uygun segmentini döndürecek hizmet çalışanı kodu basit değildir.

Neyse ki yardıma ihtiyacı olan geliştiriciler, yaygın hizmet çalışanı kullanım alanlarını basitleştiren bir kitaplık grubu olan Workbox'u kullanabilir. workbox-range-request module, kısmi yanıtları doğrudan önbellekten sunmak için gereken tüm mantığı uygular. Bu kullanım alanı için tam tarifi Workbox belgelerinde bulabilirsiniz.

Bu yayındaki hero resim, Unsplash'taki Natalie Rhea Riggs tarafından oluşturulmuştur.