Fetch API vs XMLHttpRequest

163

Ich weiß, dass die Fetch-API Promises verwendet und beide es Ihnen ermöglichen, AJAX-Anforderungen an einen Server zu senden.

Ich habe gelesen, dass die Fetch-API einige zusätzliche Funktionen enthält, die in XMLHttpRequest(und in der Fetch-API-Polyfüllung, da sie auf basiert XHR) nicht verfügbar sind .

Welche zusätzlichen Funktionen bietet die Fetch-API?

ilyabasiuk
quelle
2
Obwohl ich mich nicht sofort erinnern kann, gibt es ein oder zwei Dinge, die Sie mit XHR tun können, die Sie mit Fetch nicht tun können. Sie sagen, Sie haben gelesen, dass das Abrufen zusätzliche Möglichkeiten bietet. Diese Artikel sind nicht sehr gut, wenn sie nicht sagen, was sie sind
Jaromanda X
2
Ich habe die beiden Dinge gefunden, die Sie mit dem Abrufen nicht tun können, die Sie mit XHR können. Sie können weder Ihren eigenen Wert für das Anforderungszeitlimit beim Abrufen
festlegen
3
Abrufen ist nur eine vereinfachte Methode für die meisten Arten von XMLHttpRequests. Wenn Ihr Anwendungsfall zu Fetch passt, verwenden Sie ihn. Wenn Sie es genau angehen, ist die XMLHttpRequest-API für das, wofür die meisten Leute sie verwenden, hässlich. Fetch war ein Versuch, eine sauberere Möglichkeit zu bieten, Dinge zu tun, für die keine Bibliothek erforderlich ist, die um XMLHttpRequest gewickelt ist, um sie schmackhaft zu machen.
jfriend00
1
Es hat reine Unterstützung in Browsern ( caniuse.com/#search=fetch ), also gibt es eine Polifill dafür github.com/github/fetch , die über xhr
ilyabasiuk
4
@Marco - Wie kann man nicht sagen, dass fetch(url).then(function(data) (...));das nicht einfacher ist, als XMLHttpRequestdasselbe zu tun? Es kann viele andere Funktionen haben, aber meine Güte, es ist sicher einfacher für allgemeine Dinge zu verwenden. Es ist eine bereinigte API.
jfriend00

Antworten:

120

Es gibt einige Dinge, die Sie mit Fetch und nicht mit XHR tun können:

  • Sie können die Cache-API mit den Anforderungs- und Antwortobjekten verwenden.
  • Sie können durchführen no-cors Anforderungen und eine Antwort von einem Server erhalten, der CORS nicht implementiert. Sie können nicht direkt über JavaScript auf den Antworttext zugreifen, aber Sie können ihn mit anderen APIs (z. B. der Cache-API) verwenden.
  • Streaming-Antworten (mit XHR wird die gesamte Antwort im Speicher gepuffert, mit Fetch können Sie auf den Low-Level-Stream zugreifen). Dies ist noch nicht in allen Browsern verfügbar, wird aber bald verfügbar sein.

Es gibt einige Dinge, die Sie mit XHR tun können, die Sie mit Fetch noch nicht tun können, die jedoch früher oder später verfügbar sein werden (lesen Sie den Abschnitt "Zukünftige Verbesserungen" hier: https: //hacks.mozilla .org / 2015/03 / this-api-is-so-fetching / ):

  • Eine Anfrage abbrechen (dies funktioniert jetzt in Firefox und Edge, wie @sideshowbarker in seinem Kommentar erklärt);
  • Fortschritt melden.

Dieser Artikel https://jakearchibald.com/2015/thats-so-fetch/ enthält eine detailliertere Beschreibung.

Marco
quelle
1
Die Spezifikation für die Fetch-API sieht jetzt die Stornierung vor. Der Support wurde bisher in Firefox 57 und Edge 16 ausgeliefert. Demos: fetch-abort-demo-edge.glitch.me , mdn.github.io/dom-examples/abort-api . Und es gibt offene Chrome & Webkit-Feature-Bugs bugs.chromium.org/p/chromium/issues/detail?id=750599 , bugs.webkit.org/show_bug.cgi?id=174980 . Anleitung: developer.google.com/web/updates/2017/09/abortable-fetch , developer.mozilla.org/en-US/docs/Web/API/AbortSignal#Examples . Und Beispiel in der Stack Overflow-Antwort unter stackoverflow.com/a/47250621/441757
Sideshowbarker
1
Ein weiterer Unterschied besteht darin, dass fetchAnforderungen in den Entwicklertools nicht wiedergegeben werden können.
Parziphal
Und meiner Erfahrung nach fetchkann ich Dateien anfordern, XHR jedoch nicht.
D. Pardal
64

holen

  • Fehlen einer integrierten Methode zum Konsumieren von Dokumenten
  • Es gibt noch keine Möglichkeit, eine Zeitüberschreitung festzulegen
  • Der Inhaltstyp-Antwortheader kann nicht überschrieben werden
  • Wenn der Header für die Inhaltslänge vorhanden, aber nicht verfügbar ist, ist die Gesamtlänge des Körpers während des Streamings unbekannt
  • ruft den Abbruch-Handler des Signals auf, auch wenn die Anforderung abgeschlossen wurde
  • Kein Upload-Fortschritt (Unterstützung für ReadableStreamInstanzen als Anforderungskörper steht noch aus )

XHR

  • Es gibt keine Möglichkeit, keine Cookies zu senden (abgesehen von der Verwendung des nicht standardmäßigen mozAnonFlags oder des AnonXMLHttpRequestKonstruktors).
  • FormDataInstanzen können nicht zurückgegeben werden
  • hat kein Äquivalent zu fetch's no-corsModus
  • Folgen Sie immer den Weiterleitungen
Knu
quelle
13
fetchfehlt auch Fortschritt. Mit XHR können Sie den Fortschritt des progressEreignisses
verfolgen
1
"Der Inhaltstyp-Header der Antwort kann nicht überschrieben werden" ... dies ist zunächst nur eine schlechte Idee. Der Inhaltstyp bestimmt, was zurückgegeben werden soll, und das BACKEND SOLLTE dies dem Frontend vorschreiben. Tatsächlich sollte der Inhaltstyp der "EINZIGE HEADER" für den Typ sein, da das, was angefordert wird, zurückgegeben werden soll. Wenn Sie etwas anderes als eine spezielle Subdomain oder etwas anderes wünschen, können Sie bestimmte Funktionen separat behandeln. Sie versuchen, eine 1% -Regel 99% aller Kehlen niederzudrücken.
Orubel
@Knu yep und jetzt sind wir weiter fortgeschritten und können eine 90% ige Lösung einfach automatisieren und die Freak-Fälle zu unterschiedlichen Funktionen weiterleiten lassen.
Orubel
1
@rzr nicht genau, hast du Response#body.
Knu
9

Die obigen Antworten sind gut und bieten gute Einblicke, aber ich teile die gleiche Meinung wie in diesem Blogeintrag von Google-Entwicklern , da der Hauptunterschied (aus praktischer Sicht) die Bequemlichkeit des eingebauten Versprechens ist, von dem zurückgegeben wirdfetch

Anstatt Code wie diesen schreiben zu müssen

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();

Wir können Dinge aufräumen und etwas schreiben, das mit Versprechungen und moderner Syntax etwas prägnanter und lesbarer ist

fetch('./api/some.json')
    .then((response) => {
        response.json().then((data) => { 
            ... 
        });
    })
    .catch((err) => { ... });
Felipe
quelle
8
@TheOpti Sie können die grundlegende Abrufunterstützung in IE 11 mehrfach ausfüllen. Sie können IE11 auch in vielen Projekten als unterstützten Browser löschen, da in vielen Benutzerbasen die IE 11-Nutzung jetzt unter 1% liegt.
Devon Holcombe