Mit der Fetch API gehört das veraltete XMLHttpRequest (XHR) endgültig der Vergangenheit an. Als moderner Standard für HTTP-Abfragen ist Fetch nativ in allen aktuellen Browsern sowie in Node.js (ab Version 18) integriert. Dank einer auf Promises basierenden Struktur ermöglicht sie sauberen, asynchronen Code ohne externe Abhängigkeiten wie Axios oder jQuery.ajax().
Daten abrufen: Der klassische GET-Request
// Einfacher GET-Request
const response = await fetch('https://api.example.com/users');
const users = await response.json();
console.log(users);
// Mit robuster Fehlerbehandlung
async function getUsers() {
const response = await fetch('https://api.example.com/users');
if (!response.ok) {
throw new Error(`HTTP-Fehler ${response.status}: ${response.statusText}`);
}
return response.json();
}
Wichtig zu wissen: Ein Aufruf von fetch() schlägt nur bei echten Netzwerkfehlern fehl (z. B. wenn der Server komplett offline ist). HTTP-Statuscodes wie 404 oder 500 lösen keinen Promise-Reject aus. Deshalb ist die manuelle Überprüfung von response.ok unerlässlich.
Daten manipulieren: POST, PUT und DELETE
const response = await fetch('https://api.example.com/users', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer eyJhbGci...',
},
body: JSON.stringify({
name: 'Alice',
email: '[email protected]',
}),
});
const newUser = await response.json();
await fetch('https://api.example.com/users/123', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Alice Updated' }),
});
await fetch('https://api.example.com/users/123', {
method: 'DELETE',
headers: { 'Authorization': 'Bearer token123' },
});
Antwortformate verarbeiten (Response Types)
const response = await fetch(url);
// JSON-Daten
const data = await response.json();
// Klartext (Text)
const text = await response.text();
// Binäre Daten (Bilder, Dateien)
const blob = await response.blob();
// ArrayBuffer für Rohdaten
const buffer = await response.arrayBuffer();
// Formulardaten
const formData = await response.formData();
// Antwort-Metadaten
console.log(response.status); // 200
console.log(response.statusText); // "OK"
console.log(response.ok); // true (200-299)
console.log(response.headers.get('Content-Type'));
Anfragen abbrechen mit dem AbortController
const controller = new AbortController();
// Nach 5 Sekunden automatisch abbrechen
const timeoutId = setTimeout(() => controller.abort(), 5000);
try {
const response = await fetch('https://api.example.com/data', {
signal: controller.signal,
});
clearTimeout(timeoutId);
const data = await response.json();
} catch (err) {
if (err.name === 'AbortError') {
console.log('Anfrage wegen Timeout abgebrochen');
} else {
throw err;
}
}
Datei-Upload via Multipart/Form-Data
const formData = new FormData();
formData.append('avatar', fileInput.files[0]);
formData.append('name', 'Alice');
// Wichtig: Content-Type NICHT manuell setzen – der Browser generiert die Boundary automatisch
const response = await fetch('/api/upload', {
method: 'POST',
body: formData,
});
Einen wiederverwendbaren API-Client bauen
class ApiClient {
constructor(baseUrl, token) {
this.baseUrl = baseUrl;
this.token = token;
}
async request(path, options = {}) {
const response = await fetch(`${this.baseUrl}${path}`, {
...options,
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${this.token}`,
...options.headers,
},
});
if (!response.ok) {
const error = await response.json().catch(() => ({}));
throw new Error(error.message || `HTTP ${response.status}`);
}
return response.json();
}
get(path) { return this.request(path); }
post(path, data) { return this.request(path, { method: 'POST', body: JSON.stringify(data) }); }
put(path, data) { return this.request(path, { method: 'PUT', body: JSON.stringify(data) }); }
delete(path) { return this.request(path, { method: 'DELETE' }); }
}
// Anwendung in der Praxis
const api = new ApiClient('https://api.example.com', 'token123');
const users = await api.get('/users');
const newUser = await api.post('/users', { name: 'Alice' });
Typische Fehler und wie man sie vermeidet
- Fehlende Prüfung von
response.ok: Server-Fehler (wie 404 oder 500) werden standardmäßig nicht abgefangen – prüfen Sie den Status manuell. - Manueller Content-Type bei FormData: Setzen Sie beim Upload von
FormDataniemals den HeaderContent-Type: multipart/form-datavon Hand. Der Browser muss den Boundary-Parameter dynamisch anhängen. - Mehrfaches Auslesen des Response-Bodys: Ein Response-Stream kann nur ein einziges Mal gelesen werden. Rufen Sie
response.json()nicht mehrfach auf, sondern speichern Sie das Ergebnis in einer Variablen. - Ignorieren von AbortErrors: Wenn Sie Requests über einen
AbortControllerabbrechen, wirft das Promise einen Fehler, den Ihr Exception-Handling abfangen sollte.
Kostenlose Entwickler-Tools entdecken
Formatieren Sie JSON-Antworten blitzschnell oder kodieren Sie URL-Parameter fehlerfrei.