Upewnij się, że pracownik obsługi klienta wie, co robić, gdy zostanie poproszony o odpowiedź częściową.
Niektóre żądania HTTP zawierają nagłówek Range:
, który wskazuje, że zwrócona powinna zostać tylko część pełnego zasobu. Są one często używane do strumieniowego przesyłania treści audio lub wideo, aby umożliwić wczytywanie mniejszych fragmentów multimediów na żądanie zamiast żądania całego pliku zdalnego naraz.
Skrypt service worker to kod JavaScript, który działa między aplikacją internetową a siecią i może przechwytywać wychodzące żądania sieci oraz generować dla nich odpowiedzi.
Dawniej żądania dotyczące zakresu i mechanizmy Service Worker nie współgrały ze sobą dobrze. Konieczne było podjęcie specjalnych działań, aby uniknąć niepożądanych skutków w Twoim serwisie. Na szczęście sytuacja zaczyna się zmieniać. W przeglądarkach, które działają prawidłowo, żądania zakresu będą „działać” po prostu, gdy będą przechodzić przez skrypt service worker.
Na czym polega problem?
Rozważ użycie skryptu service worker z następującym detektorem zdarzeń fetch
, który pobiera wszystkie żądania przychodzące i przekazuje je do sieci:
self.addEventListener('fetch', (event) => {
// The Range: header will not pass through in
// browsers that behave incorrectly.
event.respondWith(fetch(event.request));
});
W przypadku przeglądarek z nieprawidłowym działaniem, jeśli event.request
zawiera nagłówek Range:
, ten nagłówek jest po cichu usuwany. Żądanie odebrane przez serwer zdalny nie zawierałoby w ogóle Range:
. Niekoniecznie musi to „zepsuć” cokolwiek, ponieważ serwer może technicznie zwrócić pełną treść odpowiedzi z kodem stanu 200
, nawet jeśli w pierwotnym żądaniu występuje nagłówek Range:
. Jednak z perspektywy przeglądarki spowoduje to przesłanie większej ilości danych niż jest to ściśle konieczne.
Deweloperzy, którzy wiedzieli o tym problemie, mogą go obejść, bezpośrednio sprawdzając obecność nagłówka Range:
i nie wywołując opcji event.respondWith()
, jeśli taki występuje. Dzięki temu mechanizm Service Worker skutecznie usuwa się z obrazu generowania odpowiedzi, a zamiast niej używana jest domyślna logika sieciowa przeglądarki, która potrafi zachować żądania dotyczące zakresów.
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));
});
Można jednak śmiało powiedzieć, że większość deweloperów nie była świadoma konieczności wykonania tej czynności. Nie było też jasne, dlaczego jest to wymagane. Ostatecznie to ograniczenie było spowodowane tym, że przeglądarki musiały dostosować się do zmian w podstawowej specyfikacji, które dodały obsługę tej funkcji.
Co zostało naprawione?
Przeglądarki, które działają prawidłowo, zachowują nagłówek Range:
, gdy event.request
jest przekazywany do fetch()
. Oznacza to, że kod usługi w pierwszym przykładzie pozwoli serwerowi zdałem wyświetlić nagłówek Range:
, jeśli został on ustawiony przez przeglądarkę:
self.addEventListener('fetch', (event) => {
// The Range: header will pass through in browsers
// that behave correctly.
event.respondWith(fetch(event.request));
});
Serwer może teraz prawidłowo obsłużyć żądanie zakresu i zwrócić częściową odpowiedź z kodem stanu 206
.
Które przeglądarki działają prawidłowo?
W najnowszych wersjach Safari funkcja działa prawidłowo. Chrome i Edge od wersji 87 działają też prawidłowo.
W październiku 2020 r. Firefox nie naprawił jeszcze tego zachowania, więc podczas wdrażania kodu usługi w wersji produkcyjnej może być konieczne uwzględnienie tego problemu.
Najlepszym sposobem na sprawdzenie, czy dany przeglądarka naprawiła to zachowanie, jest sprawdzenie wiersza „Uwzględnij nagłówek zakresu w żądaniu sieci” w panelu Testy platformy internetowej.
A co z obsługą żądań zakresu z pamięci podręcznej?
Usługa typu service worker może zrobić znacznie więcej niż tylko przekazać żądanie do sieci. Typowym przypadkiem użycia jest dodawanie zasobów, takich jak pliki audio i wideo, do lokalnej pamięci podręcznej. Następnie usługa może obsługiwać żądania z tej pamięci podręcznej, całkowicie pomijając sieć.
Wszystkie przeglądarki, w tym Firefox, obsługują sprawdzanie żądań w module obsługi fetch
, sprawdzanie obecności nagłówka Range:
, a następnie lokalne realizowanie żądania za pomocą odpowiedzi 206
pochodzącej z pamięci podręcznej. Kod usługi, który ma poprawnie zanalizować nagłówek Range:
i zwrócić tylko odpowiedni segment pełnej odpowiedzi z pamięci podręcznej, nie jest jednak prosty.
Na szczęście deweloperzy, którzy potrzebują pomocy, mogą skorzystać z Workbox, czyli zestawu bibliotek upraszczających typowe przypadki użycia usług działających w tle. workbox-range-request module
implementuje całą logikę niezbędną do wyświetlania częściowych odpowiedzi bezpośrednio z pamięci podręcznej. Pełny przepis na to zastosowanie znajdziesz w dokumentacji Workboxa.
Banerem powitalnym w tym poście jest Natalie Rhea Riggs na kanale Unsplash.