JavaScript-Fetch-API-Tutorial: GET, POST, Fehlerbehandlung und Zeitüberschreitungen
Fetch ist die integrierte Methode zum Aufrufen von APIs aus JavaScript, hat jedoch eine Überraschung, die fast jeden anspricht. Erfahren Sie, wie Sie Anfragen senden, mit jeder Art von Fehler umgehen und einen kleinen Helfer erstellen, den Sie wiederverwenden können.
fetch()gibt ein Versprechen fürResponsezurück, und das Lesen des Körpers dauert eine Sekundeawait.- HTTP-Fehler wie 404 und 500 werden nicht abgelehnt, also überprüfen Sie immer
response.ok. - Um JSON zu senden, verwenden Sie
JSON.stringifyund legen Sie den HeaderContent-Typefest. - Für Fetch gibt es keine Standard-Timeout-Option. Verwenden Sie daher
AbortSignal.timeout().
Die meisten modernen Web-Apps kommunizieren ständig mit einem Server. Die JavaScript Fetch API ist die Standardmethode dafür und sie ist in Browser und in Node.js 18 und höher integriert, sodass nichts installiert werden muss.
Die grundlegende Verwendung dauert zwei Zeilen, doch viele Tutorials hören hier auf und lassen den Teil weg, der echte Fehler verursacht: die Fehlerbehandlung. Wir haben die Beispiele in diesem Handbuch auf einem kleinen lokalen Server auf Node.js 24 getestet und die angezeigte Ausgabe stammt von diesem Lauf. example.com im Code steht für Ihre eigene API. Wenn Versprechen für Sie neu sind, beginnen Sie mit der Erklärung von JavaScript-Versprechen.
Was ist die Fetch-API?
Fetch ist eine Promise-basierte Schnittstelle zum Senden von HTTP-Anfragen. Es ersetzte das ältere, rückrufgesteuerte XMLHttpRequest, und viele Projekte verwenden es jetzt, anstatt eine Bibliothek für einfache Aufrufe hinzuzufügen.
| Funktion | Holen | Axios (Bibliothek) |
|---|---|---|
| Installation | Eingebaut | Als Abhängigkeit hinzugefügt |
| JSON-Körper | Stringisieren Sie es selbst | Automatisch |
| JSON-Antwort analysieren | Anruf response.json() |
Automatisch |
| HTTP-Fehler ablehnen? | Nein | Ja, standardmäßig |
| Auszeit | Durch AbortSignal |
Eine timeout Option |
Eine GET-Anfrage
Fetch führt standardmäßig eine GET-Anfrage durch. Es gibt zwei Schritte, und jeder benötigt await: Zuerst kommen die Antwortheader an, und dann lesen Sie den Text.
const response = await fetch("https://example.com/users/1");
const user = await response.json();
console.log(user);
// { id: 1, name: 'Asha' }
Die beiden Schritte sind vorhanden, da der Textkörper möglicherweise groß ist und später als die Kopfzeilen eintrifft. In einem Browser-Skript benötigt die oberste Ebene await ein Modul, daher fügen Sie dieses normalerweise in eine async-Funktion ein. Sehen Sie sich unseren JavaScript-Async/Await-Leitfaden an.
Das Response-Objekt
Bevor Sie den Text lesen, können Sie sich die Antwort ansehen:
console.log(response.status, response.ok, response.headers.get("content-type"));
// 200 true application/json
| Eigenschaft oder Methode | Gibt dir |
|---|---|
response.ok |
true für Status 200 bis 299 |
response.status |
Der Statuscode, z. B. 404 |
response.headers.get(name) |
Ein Antwortheader |
response.json() |
Der als JSON analysierte Text |
response.text() |
Der Körper als String |
response.blob() |
Binäre Daten, beispielsweise ein Bild |
Ein Körper kann nur einmal gelesen werden. Ein zweiter Aufruf von json() schlug in unserem Test fehl:
await res.json();
await res.json();
// TypeError: Body is unusable: Body has already been read
Wenn Sie es zweimal lesen müssen, rufen Sie zuerst response.clone() auf.
Die große Überraschung: Ein 404 wirft nicht
Das ist das Wichtigste in diesem Artikel. Wir haben einen Benutzer angefordert, der nicht existiert:
const res = await fetch("https://example.com/users/999");
console.log(res.status, res.ok);
// 404 false
Es wurde keine Ausnahme ausgelöst. Was den Abruf betrifft, hat die Anfrage funktioniert: Der Server wurde erreicht und er hat geantwortet. Das Versprechen wird nur dann abgelehnt, wenn überhaupt keine brauchbare Antwort eintrifft, beispielsweise bei einem Netzwerkausfall. Code wie dieser hat also einen versteckten Fehler:
try {
const res = await fetch(url);
const data = await res.json(); // may be an error payload
showUser(data); // runs anyway for 404 and 500
} catch (error) {
showError(); // does not run for 404 or 500
}
Sehen Sie sich unseren Spickzettel für HTTP-Statuscodes an, um zu sehen, was die einzelnen Codes bedeuten.
Ein wiederverwendbarer Helfer
Wiederholen Sie diese Prüfung nicht überall. Wickeln Sie es einmal ein:
async function getJson(url, options) {
const response = await fetch(url, options);
if (!response.ok) {
throw new Error(`Request failed with status ${response.status}`);
}
return response.json();
}
try {
await getJson("https://example.com/users/999");
} catch (error) {
console.log("caught:", error.message);
}
// caught: Request failed with status 404
Jetzt landen sowohl HTTP-Fehler als auch Netzwerkfehler im selben catch. Diese kleine Funktion lohnt sich in jedem Projekt. Eine echte Version könnte auch eine Fehlermeldung aus dem Antworttext lesen und eine 204 No Content-Antwort verarbeiten, die kein JSON zum Parsen hat.
POST-JSON-Daten
Übergeben Sie ein Optionsobjekt als zweites Argument. Für JSON müssen Sie zwei Dinge selbst tun: die Daten in einen String konvertieren und den Header festlegen.
const created = await getJson("https://example.com/users", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ name: "Ben" }),
});
console.log(created);
// { id: 2, name: 'Ben', type: 'application/json' }
Unser Testserver hat den empfangenen Inhaltstyp zurückgegeben und bestätigt, dass der Header angekommen ist. Das Vergessen dieses Headers ist eine häufige Ursache für verwirrende Serverfehler, da viele Frameworks JSON nur dann analysieren, wenn es deklariert wird. Um ein Formular oder Dateien hochzuladen, übergeben Sie ein FormData-Objekt als Textkörper und setzen Sie nicht Content-Type, da der Browser selbst einen Grenzwert hinzufügen muss.
Andere Methoden und Optionen
| Option | Beispiel | Zweck |
|---|---|---|
Methode |
"PUT", "PATCH", "DELETE" |
Die HTTP-Methode |
Kopfzeilen |
{ Autorisierung: „Inhaber ...“ } |
Header anfordern |
Körper |
JSON.stringify(data) |
Der Anforderungstext |
Signal |
AbortSignal.timeout(5000) |
Stornieren |
Anmeldeinformationen |
„einschließen“ |
Ursprungsübergreifendes Senden von Cookies |
Cache |
„kein Laden“ |
Verhalten des Browser-Cache |
Wählen Sie zwischen REST und anderen API-Stilen? Unser Vergleich von REST vs. GraphQL zeigt, wie fetch jeweils zusammenpasst.
Abfragezeichenfolgen
Erstellen Sie Abfragezeichenfolgen nicht durch Zusammenfügen von Text, da diese durch Sonderzeichen unterbrochen werden. URLSearchParams übernimmt die Kodierung für Sie:
const params = new URLSearchParams({ q: "red shoes", page: 2 });
console.log(params.toString());
// q=red+shoes&page=2
await getJson(`https://example.com/search?${params}`);
// { q: 'red shoes', page: '2' }
Der Server hat red shoes korrekt empfangen und der Speicherplatz wurde wiederhergestellt.
Auszeiten und Absagen
Der Abruf wird auf einem langsamen Server lange warten, sofern Sie ihm nichts anderes mitteilen. AbortSignal.timeout() setzt eine Grenze. Unser Testendpunkt benötigte zwei Sekunden gegenüber einem Limit von 200 Millisekunden:
try {
await fetch("https://example.com/slow", { signal: AbortSignal.timeout(200) });
} catch (error) {
console.log(error.name);
}
// TimeoutError
Um den Vorgang manuell abzubrechen, beispielsweise wenn ein Benutzer eine Seite verlässt oder einen neuen Suchbegriff eingibt, verwenden Sie eine AbortController:
const controller = new AbortController();
const pending = fetch("https://example.com/slow", { signal: controller.signal });
controller.abort();
try {
await pending;
} catch (error) {
console.log(error.name);
}
// AbortError
Um mehrere Anfragen gleichzeitig auszuführen, verwenden Sie Promise.all, was viel schneller ist, als einzeln auf sie zu warten:
const [user, search] = await Promise.all([
getJson("https://example.com/users/1"),
getJson("https://example.com/search?q=a&page=1"),
]);
Jede Art von Misserfolg
Hier sehen Sie, wie die einzelnen Fehler in unserem Lauf aussahen und wie man sie voneinander unterscheiden kann:
| Situation | Was passiert | So erkennen Sie es |
|---|---|---|
| Der Server gibt 404 oder 500 zurück | Versprechen erfüllt | response.ok ist falsch |
| Der Server ist nicht erreichbar | Ablehnung mit TypeError |
fangen |
| Zeitüberschreitung erreicht | Ablehnung mit TimeoutError |
error.name |
| Manuell storniert | Ablehnung mit AbortError |
error.name |
| Der Text ist kein gültiger JSON-Code | json() lehnt ab mit SyntaxError |
fangen |
Diese letzte Reihe ist in der Produktion üblich. Ein Proxy, der eine 502 zurückgibt, sendet häufig eine HTML-Fehlerseite. Wir haben dies reproduziert und res.json() hat eine SyntaxError geworfen. Wenn Sie response.ok vor dem Parsen überprüfen, melden Sie das eigentliche Problem und nicht einen verwirrenden Parse-Fehler.
Tipp: Testen Sie diese Fehlerpfade absichtlich. Browser-Entwicklertools können den Offline-Zustand simulieren und Testtools können eine 500-Antwort simulieren. Unser Leitfaden zum API-Testen mit Postman behandelt die Überprüfung der API-Seite.
CORS und Anmeldeinformationen
In einem Browser unterliegt eine Anfrage von einem Ursprung zu einem anderen CORS, den Cross-Origin-Ressourcenfreigaberegeln. Wenn Sie einen Fehler mit der Erwähnung von Access-Control-Allow-Origin sehen, gehört der Fix zum Server, der Ihre Site zulassen muss. In Ihrem JavaScript wird der Fehler nur als generisches Problem angezeigt TypeError. Suchen Sie daher in der Browserkonsole nach der tatsächlichen Ursache. Node.js erzwingt CORS nicht, daher kann eine Anfrage, die in einem Skript funktioniert, im Browser dennoch fehlschlagen.
Standardmäßig senden Browser bei Cross-Origin-Anfragen keine Cookies. Stellen Sie bei Bedarf credentials: "include" ein und stellen Sie sicher, dass der Server dies zulässt. Fügen Sie niemals geheime API-Schlüssel in Browser-JavaScript ein, da sie jeder lesen kann. Behalten Sie sie auf Ihrem Server.
Häufige Fehler
- Nicht überprüft
response.ok. Fehlerantworten werden als Erfolg behandelt. - Das Zweite vergessen
await.response.json()gibt auch ein Versprechen zurück. - Vergessen
JSON.stringify. Ein Objekt weitergeben, während der Körper es sendet[object Object]. - Setzen von
Content-TypemitFormData. Dadurch wird die Grenze überschritten, also lassen Sie es weg. - Es gibt keine Zeitüberschreitung. Eine blockierte Anfrage kann dazu führen, dass der Spinner einer Seite auf unbestimmte Zeit läuft.
- JSON wird auf eine leere Antwort analysiert. A 204 hat keinen Text und
json()wird ausgelöst.
Fazit
Das Abrufen ist einfach, wenn Sie sich an die Hauptregel erinnern: Eine Antwort ist nicht dasselbe wie ein Erfolg. Kopieren Sie den kleinen Helfer in Ihr Projekt, fügen Sie ein Timeout hinzu und testen Sie Ihre Fehlerpfade. Erstellen Sie im nächsten Schritt eine kleine Seite, die Daten von einer API lädt, eine klare Fehlermeldung anzeigt und es dem Benutzer ermöglicht, eine langsame Suche abzubrechen.
Häufige Fragen
Löst fetch bei einem 404-Fehler einen Fehler aus?
Nein. fetch lehnt nur ab, wenn keine Antwort empfangen wird, beispielsweise bei einem Netzwerkfehler. Überprüfen Sie bei HTTP-Fehlern „response.ok“ oder „response.status“ selbst.
Wie sende ich JSON mit Fetch?
Setzen Sie die Methode auf POST, fügen Sie einen Content-Type-Header von application/json hinzu und übergeben Sie die Daten als Text über JSON.stringify.
Warum brauche ich beim Abrufen zwei Wartevorgänge?
Der erste wird aufgelöst, sobald die Antwortheader eintreffen. Der zweite wartet darauf, dass der Text heruntergeladen und analysiert wird, was später passieren kann.
Wie stelle ich beim Abruf ein Timeout ein?
Passsignal: AbortSignal.timeout(5000) in den Optionen. Die Anfrage wird dann mit einem TimeoutError abgelehnt, wenn sie länger als so viele Millisekunden dauert.
Ist Fetch in Node.js verfügbar?
Ja. Fetch ist weltweit in Node.js 18 und höher verfügbar. Ältere Versionen benötigen ein Paket, CORS-Regeln gelten jedoch nur in Browsern.
Lerne weiter
Benötigen Sie Hilfe beim Testen, WordPress oder SEO?
Wir helfen Teams, bessere Software zu liefern und ihre Websites zu erweitern. Sagen Sie uns, woran Sie gerade arbeiten, und wir schlagen Ihnen einen klaren nächsten Schritt vor.
Weitere Anleitungen finden Sie unter Tests, KI und moderne Entwicklung
Hat Ihnen dieser Artikel gefallen? Wählen Sie ein Thema und springen Sie direkt in unsere neuesten Tutorials.
KI-Halluzinationen erklärt: Warum Sprachmodelle Dinge erfinden und wie man sie reduziert
KI-Halluzinationen erklärt: Was sie sind, warum Sprachmodelle sie produzieren, gängige Typen, wie man sie mit Erdung und Eingabeaufforderungen reduz…
Artikel lesen →DevOpsErklärte Umgebungsvariablen: .env-Dateien, Geheimnisse und Konfiguration richtig gemacht
Umgebungsvariablen anhand von Python-Beispielen erklärt, die wir ausgeführt haben: Sie lesen und festlegen, warum jeder Wert ein String ist, .env-Da…
Artikel lesen →SoftwareentwicklungAPI-Ratenbegrenzung erklärt: Algorithmen, Header und Behandlung von 429-Fehlern
API-Ratenbegrenzung anhand einer von uns durchgeführten Simulation erklärt: Token-Bucket, festes Fenster, gleitendes Fenster, 429 Antworten, Ratenbe…
Artikel lesen →TestautomatisierungSpott in Python: unittest.mock, Patch und die Fehler, die Tests zum Lügen machen
Mocking in Python mit unittest.mock, getestet: Mock und return_value, side_effect, Patchen, wo ein Name verwendet wird, Spezifikation und Autospec, …
Artikel lesen →SoftwaretestsCode-Abdeckung erklärt: Leitungs- und Zweigstellenabdeckung und was 100 % wirklich bedeutet
Erklärung der Codeabdeckung anhand eines echten Coverage.py-Laufs: Zeilen-, Zweig- und Bedingungsabdeckung, Lesen eines Berichts, warum bei 100 % Ab…
Artikel lesen →Datenbanken & SQLDELETE vs. TRUNCATE vs. DROP in SQL: Unterschiede, Rollback und Verwendungszweck
DELETE vs. TRUNCATE vs. DROP erklärt mit getestetem SQL: was jeweils entfernt wird, Rollback, Trigger, Identitätsrücksetzung, Geschwindigkeit und wi…
Artikel lesen →Datenbanken & SQLErklärte SQL-Ansichten: Erstellen, nutzen und vermeiden Sie Fallstricke mit Beispielen
SQL-Ansichten anhand der von uns ausgeführten Abfragen erklärt: Erstellen einer Ansicht, Live-Ergebnisse, Ausblenden von Spalten, Leistung, aktualis…
Artikel lesen →SoftwareentwicklungTypeScript-Schnittstelle vs. Typ: Echte Unterschiede, getestet mit dem Compiler
TypeScript-Schnittstelle vs. Typ, überprüft mit dem echten Compiler: Was beide können, was nur einer kann, Deklarationszusammenführung, Erweiterunge…
Artikel lesen →SoftwareentwicklungPython *args und **kwargs erklärt: Flexible Funktionen mit klaren Beispielen
Python *args und **kwargs erklärt mit Code, den wir ausgeführt haben: Packen und Entpacken, Parameterreihenfolge, Nur-Schlüsselwort- und Nur-Positio…
Artikel lesen →SoftwareentwicklungPython-Lambda-Funktionen: Syntax, tatsächliche Verwendung und wann man sie nicht verwendet
Python-Lambda-Funktionen erklärt mit Code, den wir ausgeführt haben: Syntax, Sortierung mit Schlüssel, Karte und Filter, Abschlüsse, die Late-Bindin…
Artikel lesen →Künstliche IntelligenzWas sind KI-Agenten? Wie sie funktionieren, mit einer einfachen Agentenschleife, die Sie ausführen können
Was sind KI-Agenten? Eine einfache Anleitung zur Agentenschleife, zu Tools, Speicher und Leitplanken, mit einer kleinen Python-Schleife, die wir aus…
Artikel lesen →DevOpsÜberwachung vs. Beobachtbarkeit: Der wahre Unterschied, mit Protokollen, Metriken und Traces
Überwachung vs. Beobachtbarkeit erklärt: bekannte und unbekannte Fehler, Protokolle, Metriken und Spuren, eine exemplarische Vorgehensweise für Chec…
Artikel lesen →DevOpsDocker-Volumes vs. Bind Mounts: Containerdaten auf die richtige Art und Weise beibehalten
Docker-Volumes vs. Bind-Mounts erklärt: Warum Containerdaten verschwinden, benannte Volumes, Bind-Mounts, tmpfs, Compose-Beispiele, Backups, Berecht…
Artikel lesen →TestautomatisierungTDD vs. BDD: Hauptunterschiede, eine Funktion, die auf beide Arten entwickelt wurde und wann sie jeweils verwendet werden sollte
TDD vs. BDD erklärt mit einer Rabattfunktion, die in beide Richtungen aufgebaut ist: Rot-Grün-Refaktor mit Code, den wir ausgeführt haben, Gegeben-W…
Artikel lesen →SoftwaretestsBenutzerakzeptanztests (UAT): Prozess, Checkliste und reale Beispiele
Benutzerakzeptanztests erklärt: Wer führt ihn durch, wie unterscheidet er sich von der Qualitätssicherung, ein siebenstufiger Prozess, eine UAT-Test…
Artikel lesen →Datenbanken & SQLErklärte SQL-NULL-Werte: IS NULL, COALESCE, NULLIF und die zu vermeidenden Fallen
SQL-NULL-Werte, die mit von uns ausgeführten Abfragen erklärt wurden: dreiwertige Logik, IS NULL, COALESCE, NULLIF, wie Aggregate, Joins und Sortier…
Artikel lesen →Datenbanken & SQLSQL CASE WHEN-Anweisung: Syntax, reale Beispiele und häufige Fehler
SQL CASE WHEN anhand der von uns ausgeführten Abfragen erklärt: einfache und durchsuchte Formulare, Bedingungsreihenfolge, Pivots mit SUM, COUNT-Tri…
Artikel lesen →SoftwareentwicklungWas ist JWT? JSON-Web-Tokens anhand eines funktionierenden Beispiels erklärt
Was ist JWT? JSON Web Tokens erklärt: die drei Teile, ein Token, das in dem von uns ausgeführten Code erstellt und manipuliert wurde, JWT vs. Sitzun…
Artikel lesen →SoftwareentwicklungErklärte JavaScript-Ereignisschleife: Aufrufstapel, Mikrotasks und Timer mit Beispielen
Die JavaScript-Ereignisschleife wurde mit dem von uns ausgeführten Code erklärt: Aufrufstapel, Aufgaben- und Mikrotask-Warteschlangen, warum setTime…
Artikel lesen →SoftwareentwicklungErklärung von Python-Generatoren und -Ertrag: Sparen Sie Speicher mit echten Beispielen
Python-Generatoren und Yield anhand des von uns ausgeführten Codes erklärt: wie sie angehalten und fortgesetzt werden, gemessene Speichereinsparunge…
Artikel lesen →Künstliche IntelligenzWas sind Einbettungen? Vektoren und Kosinusähnlichkeit einfach erklärt
Was sind Einbettungen? Ein Leitfaden in einfacher Sprache zu Vektoren, Kosinusähnlichkeit und semantischer Suche, mit einem kleinen Beispiel, das wi…
Artikel lesen →DevOpsBlau-Grün vs. Canary-Bereitstellung: Unterschiede, Kompromisse und Auswahl
Blue-Green vs. Canary-Bereitstellung erklärt: Funktionsweise, Kosten, Risiko und Rollback, stabiles Benutzer-Bucketing, das wir getestet haben, Date…
Artikel lesen →TestautomatisierungFlaky-Tests: Was sie verursacht und wie man sie endgültig behebt
Flaky-Tests wurden anhand von Demos erklärt, die wir durchgeführt haben: die Hauptursachen, wie man sie bestätigt und diagnostiziert, richtige Korre…
Artikel lesen →SoftwaretestsLasttest vs. Stresstest: Unterschiede, Metriken und k6-Beispiele
Erläuterungen zu Lasttests und Stresstests: Was die einzelnen Tests beweisen, Spike- und Soak-Tests, welche Kennzahlen wichtig sind, warum Durchschn…
Artikel lesen →SoftwaretestsTestfall vs. Testszenario: Hauptunterschiede, Beispiele und wann man sie jeweils verwendet
Testfall vs. Testszenario erklärt: klare Definitionen, eine Tabelle nebeneinander, eine Funktion zum Zurücksetzen von Passwörtern, die von Szenarios…
Artikel lesen →Datenbanken & SQLSQL-Abfrageoptimierung: Ausführungspläne lesen und langsame Abfragen mit Zeitvorgaben beheben
An einer Million Zeilen getestete SQL-Abfrageoptimierung: Ausführungspläne lesen, die richtigen Indizes hinzufügen, nicht sargierbare Filter korrigi…
Artikel lesen →Datenbanken & SQLSQL UNION vs. UNION ALL: Unterschiede, Beispiele und getestete Leistung
SQL UNION vs. UNION ALL anhand der von uns ausgeführten Abfragen erklärt: Duplikate, die Regeln, denen beide folgen, ein echter Datenfehler, gemesse…
Artikel lesen →SoftwareentwicklungTutorial zur JavaScript-Abruf-API: GET, POST, Fehlerbehandlung und Zeitüberschreitungen
Ein JavaScript-Abruf-API-Tutorial, das auf einem lokalen Server getestet wurde: GET und POST, warum 404 nicht ausgelöst wird, ein wiederverwendbarer…
Artikel lesen →SoftwareentwicklungUmgang mit Python-Dateien: Lesen, Schreiben, CSV, JSON und Pathlib mit Beispielen
Die Handhabung von Python-Dateien wird anhand des von uns ausgeführten Codes erklärt: Öffnungsmodi, Lesen großer Dateien, CSV, JSON, Pathlib, Binärd…
Artikel lesen →SoftwareentwicklungGit merge vs rebase: Unterschiede, Beispiele und wann man was nutzt
Git merge vs rebase erklärt mit echter Log-Ausgabe, einer Vergleichstabelle, der goldenen Regel des Rebase und einem sicheren Team-Workflow.
Artikel lesen →SoftwareentwicklungPython List Comprehension: Syntax, Beispiele und wann man darauf verzichtet
Python List Comprehension erklärt: Syntax, Filter, if-else, verschachtelte Schleifen, gemessene Zeiten und Fälle, in denen eine normale for-Schleife…
Artikel lesen →Datenbanken & SQLSQL Joins erklärt mit Beispielen (Inner, Left, Right, Full)
SQL Joins Schritt für Schritt mit Beispieltabellen und Abfragen verstehen: INNER, LEFT, RIGHT, FULL, CROSS und SELF, plus typische Fehler und Perfor…
Artikel lesen →