Service Worker'da aralık isteklerini işleme

Kısmi yanıt istendiğinde ne yapılacağını hizmet çalışanınızın bildiğinden emin olun.

Bazı HTTP istekleri, tüm kaynağın yalnızca bir kısmının döndürülmesi gerektiğini belirten bir Range: üst bilgisi içerir. Uzak dosyanın tamamının tek seferde tamamının istenmesi yerine, küçük medya parçalarının isteğe bağlı olarak yüklenmesine olanak tanımak için genellikle ses veya video içeriği akışı için kullanılırlar.

Hizmet çalışanı, web uygulamanız ile ağ arasında yer alan, giden ağ isteklerine müdahale edip bu istekler için yanıt oluşturan JavaScript kodudur.

Daha önce aralık istekleri ve Service Worker'lar birlikte iyi performans göstermedi. Service Worker'ınızda kötü sonuçları önlemek için özel adımlar atılması gerekiyordu. Neyse ki bu durum değişmeye başlıyor. Doğru davranışı gösteren tarayıcılarda, aralık istekleri bir Service Worker'dan geçerken "sadece çalışır".

Sorun nedir?

Gelen her isteği alıp ağa ileten aşağıdaki fetch etkinlik işleyiciye sahip bir hizmet çalışanı düşünün:

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: üstbilgisi içerirse bu başlık sessizce kaldırılır. Uzak sunucu tarafından alınan istek hiçbir şekilde Range: içermiyor. Sunucunun, orijinal istekte Range: üstbilgisi olsa bile teknik olarak 200 durum kodu ile tüm yanıt gövdesini döndürmesine izin verildiğinden, bu hiçbir şeyi "kırma" anlamına gelmez. Ancak, tarayıcı açısından kesinlikle gerekenden daha fazla veri aktarılmasına neden olur.

Bu davranışın farkında olan geliştiriciler, Range: üstbilgisinin olup olmadığını açıkça kontrol ederek ve varsa event.respondWith() çağrısı yapmayarak bu sorunu çözebilir. Bu sayede Service Worker kendisini yanıt oluşturma resminden etkili bir şekilde kaldırır. Bunun yerine aralık isteklerinin nasıl korunacağını bilen varsayılan tarayıcı ağ iletişimi 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 yapmaya ihtiyacı olduğunun farkında olmadığını söylemek yanlış olmaz. Buna neden ihtiyaç duyulduğu da açık değildi. Sonuçta bu sınırlama, tarayıcıların temel teknik özelliklerde yapılan değişikliklere uyum sağlamasından ve dolayısıyla bu işlev için destek sunmaktan kaynaklanmıştı.

Neler düzeltildi?

Doğru şekilde çalışan tarayıcılar, event.request fetch() yöntemine iletildiğinde Range: üstbilgisini korur. Bu, ilk örneğimdeki Service Worker 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 kodu ile kısmi bir yanıt döndürme şansına sahip olur.

Hangi tarayıcılar düzgün çalışıyor?

Safari'nin son sürümleri doğru işlevselliğe sahiptir. 87 sürümünden itibaren Chrome ve Edge de düzgün çalışır.

Firefox, Ekim 2020'de bu davranışı henüz düzeltmemiştir. Bu nedenle, Service Worker'ınızın kodunu üretime dağıtırken bu durumu göz önünde bulundurmanız gerekebilir.

Web Platformu Testleri kontrol panelinin "Aralık başlığını ağ isteğine dahil et" satırının işaretlenmesi, belirli bir tarayıcının bu davranışı düzeltip düzeltmediğini onaylamanın en iyi yoludur.

Önbellekten aralık istekleri yayınlama nasıl olacak?

Service Worker'lar, bir isteği ağa iletmekten çok daha fazlasını yapabilir. Yaygın bir kullanım alanı, yerel önbelleğe ses ve video dosyaları gibi kaynaklar eklemektir. Böylece hizmet çalışanı, ağı tamamen atlayarak bu önbellekten gelen istekleri yerine getirebilir.

Firefox da dahil olmak üzere tüm tarayıcılar, bir fetch işleyicisinin içindeki istekleri denetlemeyi, Range: üst bilgisinin olup olmadığını kontrol etmeyi ve ardından bir önbellekten gelen 206 yanıtıyla isteğin yerel olarak yerine getirilmesini destekler. Bununla birlikte, Range: üstbilgisini düzgün bir şekilde ayrıştıran ve önbelleğe alınan yanıtın yalnızca uygun segmentini döndüren Service Worker kodu önemsiz değildir.

Neyse ki yardım almak isteyen geliştiriciler, yaygın Service Worker kullanım alanlarını basitleştiren bir kitaplık kümesi olan Workbox'tan yararlanabilirler. workbox-range-request module, kısmi yanıtları doğrudan önbellekten sunmak için gereken tüm mantığı uygular. Bu kullanım alanının kapsamlı tarifini Workbox dokümanlarında bulabilirsiniz.

Bu gönderideki hero resim, Unsplash'teki Natalie Rhea Riggs'e aittir.