Fetch API vs XMLHttpRequest

163

Wiem, że używa Fetch API Promise s i oba pozwalają na wysyłanie żądań AJAX do serwera.

Przeczytałem, że Fetch API ma kilka dodatkowych funkcji, które nie są dostępne w XMLHttpRequest(i w polyfill Fetch API, ponieważ jest na nim oparty XHR).

Jakie dodatkowe możliwości ma Fetch API?

ilyabasiuk
źródło
2
Chociaż nie mogę sobie przypomnieć na miejscu, jest jedna lub dwie rzeczy, które możesz zrobić z XHR, których nie możesz zrobić z aportem. Mówisz, że czytałeś, że pobieranie ma dodatkowe możliwości, te artykuły nie są zbyt dobre, jeśli nie mówią, czym są
Jaromanda X
2
znalazłem dwie rzeczy, których nie możesz zrobić z pobieraniem, a które możesz z XHR ... nie możesz ustawić własnej wartości dla limitu czasu żądania w pobieraniu, ani nie możesz uzyskać zdarzeń postępu
Jaromanda X
3
Pobieranie to tylko uproszczony sposób wykonywania czynności dla większości typów XMLHttpRequests. Jeśli Twój przypadek użycia pasuje do tego, co robi Fetch, użyj go. Kiedy już się do tego zabierasz, API XMLHttpRequest jest brzydkie do tego, do czego większość ludzi go używa. Fetch był próbą zaoferowania czystszego sposobu robienia rzeczy, które nie wymagają biblioteki owiniętej wokół XMLHttpRequest, aby była łatwa do przyjęcia.
jfriend00
1
Ma czyste wsparcie w przeglądarkach ( caniuse.com/#search=fetch ), więc jest dla niego polifill github.com/github/fetch , który działa powyżej xhr
ilyabasiuk
4
@Marco - Jak możesz nie powiedzieć, że fetch(url).then(function(data) (...));nie jest to prostsze niż użycie XMLHttpRequestdo tego samego? Może mieć wiele innych funkcji, ale rany, z pewnością jest prostszy w użyciu do zwykłych rzeczy. JEST to wyczyszczone API.
jfriend00

Odpowiedzi:

120

Jest kilka rzeczy, które możesz zrobić za pomocą pobierania, a nie za pomocą XHR:

  • Możesz używać Cache API z obiektami żądań i odpowiedzi;
  • Możesz występować no-cors żądania, uzyskując odpowiedź z serwera, który nie implementuje mechanizmu CORS. Nie możesz uzyskać dostępu do treści odpowiedzi bezpośrednio z JavaScript, ale możesz jej używać z innymi API (np. Cache API);
  • Odpowiedzi strumieniowe (dzięki XHR cała odpowiedź jest buforowana w pamięci, dzięki funkcji pobierania będziesz mieć dostęp do strumienia niskiego poziomu). Nie jest to jeszcze dostępne we wszystkich przeglądarkach, ale wkrótce będzie.

Jest kilka rzeczy, które możesz zrobić z XHR, a których nie możesz jeszcze zrobić za pomocą pobierania, ale będą one dostępne wcześniej czy później (przeczytaj akapit „Przyszłe ulepszenia” tutaj: https: //hacks.mozilla .org / 2015/03 / this-api-is-so-fetching / ):

  • Przerwij żądanie (działa to teraz w Firefoksie i Edge, jak wyjaśnia @sideshowbarker w swoim komentarzu);
  • Zgłoś postęp.

Ten artykuł https://jakearchibald.com/2015/thats-so-fetch/ zawiera bardziej szczegółowy opis.

Marco
źródło
1
Specyfikacja interfejsu Fetch API przewiduje teraz anulowanie. Do tej pory wsparcie zostało udostępnione w przeglądarkach Firefox 57 i Edge 16. Dema: fetch-abort-demo-edge.glitch.me , mdn.github.io/dom-examples/abort-api . Są też otwarte błędy funkcji Chrome i Webkit bugs.chromium.org/p/chromium/issues/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980 . Instrukcje: developers.google.com/web/updates/2017/09/abortable-fetch , developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples . I przykład w odpowiedzi Stack Overflow na stackoverflow.com/a/47250621/441757
sideshowbarker
1
Inną różnicą jest to, że fetchżądań nie można odtworzyć w Narzędziach dla programistów.
Parziphal
Z mojego doświadczenia wynika, że fetchmogę prosić o pliki, ale XHR nie.
D. Pardal,
64

sprowadzać

  • brakuje wbudowanej metody konsumowania dokumentów
  • nie sposób ustawić limit czasu jeszcze
  • nie może zastąpić nagłówka odpowiedzi typu treści
  • jeśli nagłówek odpowiedzi Content-Length jest obecny, ale nie jest ujawniony , całkowita długość treści jest nieznana podczas przesyłania strumieniowego
  • wywoła procedurę obsługi przerwania sygnału, nawet jeśli żądanie zostało zakończone
  • brak postępu w przesyłaniu (obsługa ReadableStreaminstancji jako treści żądań jeszcze nie nadeszła )

XHR

  • nie ma możliwości, aby nie wysyłać ciasteczek (poza użyciem niestandardowej mozAnonflagi lub AnonXMLHttpRequestkonstruktora)
  • nie może wrócić FormData instancji
  • nie ma odpowiednika fetch'sno-cors trybu
  • zawsze podążaj za przekierowaniami
Knu
źródło
13
fetchbrakuje również postępu. dzięki XHR możesz śledzić postępy w progresswydarzeniu
rzr
1
„nie można zastąpić nagłówka odpowiedzi typu treści” ... to po prostu zły pomysł. typ zawartości określa, co ma zostać zwrócone, a BACKEND POWINIEN dyktować to frontendowi. W PORZĄDKU, typ zawartości powinien być „TYLKO NAGŁÓWKIEM” dla typu, ponieważ to, co jest wymagane, powinno być zwrócone. Jeśli chcesz coś innego, wyświetlaj ze specjalnej subdomeny lub czegoś innego, abyś mógł oddzielnie obsługiwać określone funkcje. Próbujesz wymusić regułę 1% w dół 99% wszystkich gardeł.
Orubel,
@Knu tak, a teraz jesteśmy bardziej zaawansowani i możemy łatwo zautomatyzować 90% rozwiązanie i pozwolić, aby dziwaczne przypadki kierowały się do innej funkcjonalności.
Orubel
1
@rzr nie do końca, masz Response#body.
Knu
9

Powyższe odpowiedzi są dobre i zapewniają dobre spostrzeżenia, ale podzielam tę samą opinię, którą podzieliłem w tym wpisie na blogu Google Developers , ponieważ główną różnicą (z praktycznego punktu widzenia) jest wygoda wbudowanej obietnicy zwróconej zfetch

Zamiast pisać taki kod

function reqListener() {
    var data = JSON.parse(this.responseText);
}

function reqError(err) { ... }

var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();

możemy wszystko uporządkować i napisać coś bardziej zwięzłego i czytelnego z obietnicami i nowoczesną składnią

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Felipe
źródło
8
@TheOpti Możesz wypełnić podstawową obsługę pobierania w IE 11. W wielu projektach możesz po prostu porzucić IE11 jako obsługiwaną przeglądarkę, ponieważ w wielu bazach użytkowników użycie IE 11 jest teraz poniżej 1%.
Devon Holcombe