Mit fetch()
können Sie Netzwerkanfragen ähnlich wie XMLHttpRequest (XHR) senden. Der Hauptunterschied besteht darin, dass die Fetch API Promises verwendet, die eine einfachere API haben, um die komplizierten Callbacks in der XMLHttpRequest API zu vermeiden.
Wenn Sie Promises noch nie verwendet haben, lesen Sie den Artikel Einführung in JavaScript-Promises.
Grundlegende Abrufanfrage
Hier ein Beispiel, das mit XMLHttpRequest
und dann mit fetch
implementiert wurde. Wir möchten eine URL anfordern, eine Antwort erhalten und parsen,
im JSON-Format.
XMLHttpRequest
Ein XMLHttpRequest
benötigt zwei Listener, um den Erfolg zu verarbeiten
sowie einen Aufruf von open()
und send()
.
Beispiel aus den MDN-Dokumenten
function reqListener () {
const data = JSON.parse(this.responseText);
console.log(data);
}
function reqError (err) {
console.log('Fetch Error :-S', err);
}
const 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(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(err => {
console.log('Fetch Error :-S', err);
});
Für die fetch()
-Anfrage ist nur ein Aufruf erforderlich, um die gleiche Arbeit wie im XHR-Beispiel zu erledigen. Um die Antwort zu verarbeiten, prüfen wir zuerst, ob der Antwortstatus
200 und parsen Sie dann die Antwort als JSON. Die Antwort auf eine fetch()
-Anfrage ist ein Stream-Objekt. Das bedeutet, dass nach dem Aufrufen der json()
-Methode ein Promise zurückgegeben wird.
Der Stream erfolgt asynchron.
Antwortmetadaten
Im vorherigen Beispiel wurde der Status des Response-Objekts und die Parse-Methode für die Antwort als JSON gezeigt. So greifen Sie auf andere Metadaten zu, auf die Sie möglicherweise zugreifen möchten, z. B. auf Header:
fetch('users.json').then(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 der Antwort eine response.type
von „basic
“, „cors
“ oder „opaque
“ zugewiesen. Mit diesen types
wird angegeben, woher die Ressource stammt. Sie können sie verwenden, um zu bestimmen, wie das Antwortobjekt behandelt werden soll.
Wenn der Browser eine Ressource vom selben Ursprung anfordert, enthält die Antwort einen
basic
-Typ mit Einschränkungen dafür, was Sie in der Antwort sehen können.
Wenn eine Anfrage für eine Ressource an einem anderen Ursprung gestellt wird und dieser Ursprung
CORs-Header: Der Typ ist cors
. cors
-Antworten ähneln basic
-Antworten, aber die zu sehenden Header sind auf Cache-Control
, Content-Language
, Content-Type
, Expires
, Last-Modified
und Pragma
beschränkt.
opaque
-Antworten stammen von einem anderen Ursprung, der keine CORS-Header zurückgibt. Bei einer opaken Antwort können wir
die zurückgegebenen Daten zu lesen oder den Status der Anfrage anzuzeigen, d. h., Sie können die
ob die Anfrage erfolgreich war.
Sie können einen Modus für eine Abrufanfrage definieren, sodass nur bestimmte Anfragetypen gelöst werden muss. Sie können folgende Modi festlegen:
same-origin
ist nur bei Anfragen für Assets mit demselben Ursprung erfolgreich und lehnt alle anderen Anträge ab.cors
erlaubt Anfragen für Assets mit demselben Ursprung und anderen Ursprüngen, die die entsprechenden CORS-Header zurückgeben.cors-with-forced-preflight
führt vor jeder Anfrage eine Preflight-Prüfung durch.no-cors
ist für Anfragen an andere Ursprünge gedacht, die keine CORS-Header haben und eineopaque
-Antwort zurückgeben. Wie bereits erwähnt, ist dies derzeit nicht im globalen Gültigkeitsbereich des Fensters möglich.
Um den Modus zu definieren, fügen Sie der fetch
-Anfrage als zweiten Parameter ein Optionsobjekt hinzu und definieren Sie den Modus in diesem Objekt:
fetch('http://some-site.com/cors-enabled/some.json', {mode: 'cors'})
.then(response => response.text())
.then(text => {
console.log('Request successful', text);
})
.catch(error => {
log('Request failed', error)
});
Verkettung von Versprechen
Eines der großen Merkmale von Versprechen ist die Möglichkeit, sie zu verketten. Bei fetch()
können Sie so die Logik für Abrufanfragen teilen.
Wenn Sie mit einer JSON API arbeiten, müssen Sie den Status prüfen und den JSON für jede Antwort. Sie können Ihren Code vereinfachen, indem Sie den Status und JSON-Parsing in separaten Funktionen, die Promise-Versprechen zurückgeben, und den Abruf -Anfrage, 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(data => {
console.log('Request succeeded with JSON response', data);
}).catch(error => {
console.log('Request failed', error);
});
In diesem Beispiel wird eine status
-Funktion definiert, die response.status
und
gibt entweder ein aufgelöstes Promise als
Promise.resolve()
,
oder ein abgelehntes Promise
Promise.reject()
Dies ist die erste Methode, die in der fetch()
-Kette aufgerufen wird.
Wenn das Promise erfüllt ist, ruft das Script die json()
-Methode auf, die ein zweites Promise vom response.json()
-Aufruf zurückgibt und ein Objekt mit dem geparsten JSON erstellt. Wenn das Parsing fehlschlägt,
abgelehnt und die Catch-Anweisung wird ausgeführt.
Mit dieser Struktur können Sie die Logik für alle Abrufanfragen verwenden, einfacher zu pflegen, zu lesen und zu testen.
POST-Anfrage
Manchmal muss eine Webanwendung eine API mit einer POST-Methode aufrufen und einige Parameter in den Text der Anfrage aufnehmen. Legen Sie dazu die Parameter method
und body
in den fetch()
-Optionen fest:
fetch(url, {
method: 'post',
headers: {
"Content-type": "application/x-www-form-urlencoded; charset=UTF-8"
},
body: 'foo=bar&lorem=ipsum'
})
.then(json)
.then(data => {
console.log('Request succeeded with JSON response', data);
})
.catch(error => {
console.log('Request failed', error);
});
Anmeldedaten mit einer Abrufanfrage senden
Wenn du eine Abrufanfrage mit Anmeldedaten wie Cookies senden möchtest, setze den credentials
-Wert der Anfrage auf "include"
:
fetch(url, {
credentials: 'include'
})