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 gösteren 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.

Geçmişte, aralık istekleri ve hizmet çalışanları birlikte düzgün çalışmamıştır. 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 istek Range: içermez. 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() çağrısını atlayarak bu sorunun üstesinden gelebilir. Bu sayede 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));
});

Bununla birlikte, çoğu geliştiricinin bunu yapması gerektiğinin 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 bir şekilde işleme ve 206 durum koduna sahip kısmi bir yanıt döndürme fırsatı bulur.

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

Safari'nin son sürümlerinde doğru işlevler bulunur. 87 sürümünden itibaren Chrome ve Edge de düzgün ç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.

Önbellekten aralık isteği sunma işlemi nasıl olacak?

Hizmet çalışanları, isteklerin ağa iletilmesinden ç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 gönderideki hero resim, Unsplash'teki Natalie Rhea Riggs tarafından sağlanmıştır.