Mit fetch()
können Sie Netzwerkanfragen ähnlich wie XMLHttpRequest (XHR) senden. Der Hauptunterschied besteht darin, dass die Fetch API Promises verwendet, eine einfachere API, mit der Sie die komplizierten Callbacks in der XMLHttpRequest API vermeiden können.
Wenn Sie Promise-Objekte noch nie verwendet haben, sollten Sie die Einführung in JavaScript-Promise-Objekte lesen.
Einfache Abrufanfrage
Hier ist ein Beispiel, das mit einem XMLHttpRequest
und dann mit fetch
implementiert wurde. Wir möchten eine URL anfordern, eine Antwort erhalten und sie als JSON parsen.
XMLHttpRequest
Ein XMLHttpRequest
benötigt zwei Listener, um die Erfolgs- und Fehlerfälle zu verarbeiten, sowie einen Aufruf von open()
und send()
.
Beispiel aus MDN-Dokumenten
function reqListener() {
var data = JSON.parse(this.responseText);
console.log(data);
}
function reqError(err) {
console.log('Fetch Error :-S', err);
}
var oReq = new XMLHttpRequest();
oReq.onload = reqListener;
oReq.onerror = reqError;
oReq.open('get', './api/some.json', true);
oReq.send();
Abrufen
Unsere Abrufanfrage sieht so aus:
fetch('./api/some.json')
.then(
function(response) {
if (response.status !== 200) {
console.log('Looks like there was a problem. Status Code: ' +
response.status);
return;
}
// Examine the text in the response
response.json().then(function(data) {
console.log(data);
});
}
)
.catch(function(err) {
console.log('Fetch Error :-S', err);
});
Die fetch()
-Anfrage benötigt nur einen Aufruf, um dieselbe Arbeit wie im XHR-Beispiel auszuführen. Zur Verarbeitung der Antwort prüfen wir zuerst, ob der Antwortstatus 200 lautet, und parsen die Antwort dann als JSON. Die Antwort auf eine fetch()
-Anfrage ist ein Stream-Objekt. Das bedeutet, dass nach dem Aufrufen der json()
-Methode ein Promise-Objekt zurückgegeben wird.
Der Stream erfolgt asynchron.
Antwortmetadaten
Das vorherige Beispiel zeigte den Status des Response-Objekts und wie die Antwort als JSON geparst wird. So gehen Sie mit anderen Metadaten um, auf die Sie möglicherweise zugreifen möchten, z. B. Header:
fetch('users.json').then(function(response) {
console.log(response.headers.get('Content-Type'));
console.log(response.headers.get('Date'));
console.log(response.status);
console.log(response.statusText);
console.log(response.type);
console.log(response.url);
});
Antworttypen
Wenn wir eine Abrufanfrage stellen, wird als Antwort als response.type
„basic
“, „cors
“ oder „opaque
“ zurückgegeben. Diese types
geben an, woher die Ressource stammt, und Sie können sie verwenden, um festzulegen, wie das Antwortobjekt zu behandeln ist.
Wenn der Browser eine Ressource vom selben Ursprung anfordert, hat die Antwort den Typ basic
mit Einschränkungen dafür, was Sie in der Antwort sehen können.
Wenn eine Anfrage für eine Ressource an einem anderen Ursprung gesendet wird und dieser Ursprung CORs-Header zurückgibt, ist der Typ cors
. cors
-Antworten ähneln basic
-Antworten, beschränken jedoch die Header, die Sie ansehen können, auf Cache-Control
, Content-Language
, Content-Type
, Expires
, Last-Modified
und Pragma
.
opaque
-Antworten stammen aus einem anderen Ursprung, der keine CORS-Header zurückgibt. Bei einer intransparenten Antwort können wir die zurückgegebenen Daten nicht lesen oder den Status der Anfrage einsehen, d. h., Sie können nicht prüfen, ob die Anfrage erfolgreich war.
Sie können einen Modus für eine Abrufanfrage definieren, sodass nur bestimmte Anfragetypen aufgelöst werden. Folgende Modi können festgelegt werden:
same-origin
ist nur bei Anfragen für Assets desselben Ursprungs erfolgreich und lehnt alle anderen Anfragen ab.cors
lässt Anfragen für Assets desselben und anderer Ursprünge zu, die die entsprechenden CORs-Header zurückgeben.cors-with-forced-preflight
führt eine Preflight-Prüfung durch, bevor eine Anfrage gestellt wird.no-cors
ist dazu vorgesehen, Anfragen an andere Ursprünge zu senden , die keine CORS-Header haben und zu eineropaque
-Antwort führen. Dies ist jedoch derzeit im globalen Fensterbereich nicht möglich.
Um den Modus zu definieren, fügen Sie in der fetch
-Anfrage ein Optionsobjekt als zweiten Parameter hinzu und definieren den Modus in diesem Objekt:
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(function(response) {
return response.text();
})
.then(function(text) {
console.log('Request successful', text);
})
.catch(function(error) {
log('Request failed', error)
});
Verkettung von Versprechen
Eins der großartigen Merkmale von Versprechen ist die Fähigkeit, sie miteinander zu verknüpfen. So können Sie für fetch()
die Logik für Abrufanfragen gemeinsam nutzen.
Wenn Sie mit einer JSON API arbeiten, müssen Sie den Status prüfen und den JSON-Code für jede Antwort parsen. Sie können Ihren Code vereinfachen, indem Sie den Status und das JSON-Parsing in separaten Funktionen definieren, die Promise zurückgeben, und die Abrufanfrage verwenden, um nur die endgültigen Daten und den Fehlerfall zu verarbeiten.
function status(response) {
if (response.status >= 200 && response.status < 300) {
return Promise.resolve(response)
} else {
return Promise.reject(new Error(response.statusText))
}
}
function json(response) {
return response.json()
}
fetch('users.json')
.then(status)
.then(json)
.then(function(data) {
console.log('Request succeeded with JSON response', data);
}).catch(function(error) {
console.log('Request failed', error);
});
In diesem Beispiel wird eine status
-Funktion definiert, die response.status
prüft und entweder ein aufgelöstes Promise als Promise.resolve()
oder ein abgelehntes Promise als Promise.reject()
zurückgibt.
Dies ist die erste Methode, die in der fetch()
-Kette aufgerufen wird.
Wenn das Promise aufgelöst wird, ruft das Skript die Methode json()
auf, die ein zweites Promise aus dem response.json()
-Aufruf zurückgibt und ein Objekt erstellt, das die geparste JSON-Datei enthält. Wenn das Parsing fehlschlägt, wird das Promise-Objekt abgelehnt und die Catch-Anweisung ausgeführt.
Mit dieser Struktur können Sie die Logik für alle Abrufanfragen freigeben, sodass Code einfacher verwaltet, gelesen und getestet werden kann.
POST-Anfrage
Manchmal muss eine Webanwendung eine API mit einer POST-Methode aufrufen und einige Parameter in den Text der Anfrage einfügen. Legen Sie dazu die Parameter method
und body
in den Optionen fetch()
fest:
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(function (data) {
console.log('Request succeeded with JSON response', data);
})
.catch(function (error) {
console.log('Request failed', error);
});
Anmeldedaten mit einer Abrufanfrage senden
Für eine Abrufanfrage mit Anmeldedaten wie Cookies setzen Sie den Wert credentials
der Anfrage auf "include"
:
fetch(url, {
credentials: 'include'
})