Często zdarza się, że w momencie zamknięcia strony lub aplikacji znajdują się na niej nieprzesłane dane z Analytics lub inne dane. Aby zapobiec utracie danych, niektóre witryny używają synchronicznego wywołania XMLHttpRequest(), aby strona lub aplikacja pozostała otwarta do momentu przesłania danych na serwer. Istnieją lepsze sposoby zapisywania danych, a ta metoda pogarsza wygodę użytkowników, ponieważ opóźnia zamknięcie strony nawet o kilka sekund.
Ta praktyka musi się zmienić, a przeglądarki reagują na to. Specyfikacja XMLHttpRequest()
jest już przeznaczona do wycofania i
usunięcia. Chrome 80 to pierwszy
krok w tym kierunku. Przeglądarka ta nie zezwala na synchroniczne wywołania w kilku modułach obsługi zdarzeń,
w tym beforeunload, unload, pagehide, i visibilitychange, gdy
są one wywoływane w momencie odrzucenia. WebKit również niedawno wprowadził zmianę, która implementuje
to samo zachowanie.
Krótko opiszę opcje dla tych, którzy potrzebują czasu na zaktualizowanie swoich witryn, i przedstawię alternatywy dla XMLHttpRequest().
Tymczasowe wyłączenie
Chrome chce dać deweloperom czas na usunięcie zależności od XMLHttpRequest(), dlatego oferujemy tymczasowe opcje rezygnacji.
Dołącz do testu origin
trial. W tym celu dodaj do nagłówków strony token specyficzny dla origin, który umożliwi synchroniczne wywołania XMLHttpRequest(). Ta opcja przestanie działać na krótko przed wydaniem Chrome 89, czyli w marcu 2021 r. Klienci Chrome Enterprise mogą też używać flagi zasady AllowSyncXHRInPageDismissal, która przestanie działać w tym samym czasie.
Alternatywy
Niezależnie od tego, jak wysyłasz dane z powrotem na serwer, najlepiej unikać czekania na zamknięcie strony, aby wysłać wszystkie dane naraz. Oprócz pogorszenia komfortu użytkowników zamknięcie strony jest zawodne w nowoczesnych przeglądarkach i może spowodować utratę danych, jeśli coś pójdzie nie tak. W szczególności zdarzenia zamknięcia strony często nie są wywoływane w przeglądarkach mobilnych
ponieważ w mobilnych systemach operacyjnych istnieje wiele sposobów na
zamknięcie karty lub przeglądarki bez wywołania zdarzenia unload.
W przypadku XMLHttpRequest() używanie małych ładunków było opcjonalne. Teraz jest to wymagane. Obie alternatywy mają limit przesyłania 64 KB na kontekst, zgodnie ze specyfikacją.
Utrzymywanie aktywności pobierania
Interfejs Fetch API
zapewnia niezawodny sposób obsługi interakcji z serwerem i spójny
interfejs do użycia w różnych
interfejsach API platformy. Jedną z jego opcji jest keepalive, która zapewnia, że żądanie będzie kontynuowane niezależnie od tego, czy strona, która je wysłała, pozostanie otwarta:
window.addEventListener('unload', {
fetch('/siteAnalytics', {
method: 'POST',
body: getStatistics(),
keepalive: true
});
}
Metoda fetch() ma tę zaletę, że zapewnia większą kontrolę nad tym, co jest wysyłane na serwer. W przykładzie nie pokazuję, że fetch() zwraca też obietnicę, która jest rozwiązywana za pomocą obiektu Response. Ponieważ staram się nie przeszkadzać w zamykaniu strony, nie robię z nią nic.
SendBeacon()
SendBeacon()
używa pod spodem Fetch API, dlatego ma ten sam limit ładunku 64 KB i zapewnia, że żądanie będzie kontynuowane po zamknięciu strony. Jego główną zaletą jest prostota. Umożliwia przesyłanie danych za pomocą jednego wiersza kodu:
window.addEventListener('unload', {
navigator.sendBeacon('/siteAnalytics', getStatistics());
}
Podsumowanie
Dzięki coraz większej dostępności w przeglądarkach
fetch(), XMLHttpRequest() zostanie prawdopodobnie usunięte
z platformy internetowej. Producenci przeglądarek zgadzają się, że należy go usunąć, ale zajmie to trochę czasu. Wycofanie jednego z najgorszych przypadków użycia to pierwszy krok, który poprawia komfort użytkowników.