Signatur
Beschreibung
Die Methode json() gehört zum Body-Mixin und steht daher sowohl auf Request als auch auf Response zur Verfügung. Bei einem Request liest sie den Anforderungskörper als Stream bis zum Ende, dekodiert ihn als UTF-8 und parst den Text anschließend mit derselben Logik wie JSON.parse(). Das Ergebnis kann ein Objekt, ein Array, ein String, eine Zahl, ein Boolean oder null sein.
In der Praxis braucht man Request.json() vor allem auf der Serverseite bzw. in Laufzeitumgebungen, die eingehende Anfragen als Request-Objekte liefern: in Service Workern (fetch-Event), in Edge-Funktionen (Cloudflare Workers, Vercel, Deno Deploy), in Bun, Next.js-Route-Handlern oder in Hono. Dort liest man damit den JSON-Body eines POST- oder PUT-Aufrufs aus.
Der Körper kann nur einmal gelesen werden. Nach dem Aufruf ist request.bodyUsed gleich true, und jeder weitere Leseversuch (json(), text(), formData() …) schlägt mit einem TypeError fehl. Wer den Körper mehrfach braucht, erstellt vorher mit request.clone() eine Kopie.
Das Promise wird abgelehnt, wenn der Körper kein gültiges JSON enthält (SyntaxError), leer ist oder bereits verbraucht wurde (TypeError). Eine Fehlerbehandlung mit try/catch gehört deshalb zu jedem produktiven Einsatz.
Rückgabewert
null) erfüllt wird. Es wird mit SyntaxError abgelehnt, wenn der Körper kein gültiges JSON ist, bzw. mit TypeError, wenn der Körper bereits gelesen wurde.Beispiele
Grundlagen: JSON-Body eines Request-Objekts lesen
const request = new Request('https://example.com/api/users', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ name: 'Anna', alter: 32 })
});
const daten = await request.json();
console.log(daten.name, daten.alter);
console.log(request.bodyUsed);
Edge-/Server-Handler mit Validierung und Fehlerbehandlung
// z. B. Cloudflare Worker, Deno, Bun oder Next.js-Route-Handler
export default {
async fetch(request) {
if (request.method !== 'POST') {
return new Response('Method Not Allowed', { status: 405 });
}
if (!request.headers.get('content-type')?.includes('application/json')) {
return new Response('JSON erwartet', { status: 415 });
}
let payload;
try {
payload = await request.json();
} catch (err) {
return Response.json({ fehler: 'Ungültiges JSON' }, { status: 400 });
}
if (typeof payload?.email !== 'string') {
return Response.json({ fehler: 'Feld email fehlt' }, { status: 422 });
}
return Response.json({ ok: true, email: payload.email }, { status: 201 });
}
};
Service Worker: Body loggen und Anfrage trotzdem weiterleiten
self.addEventListener('fetch', (event) => {
const { request } = event;
if (request.method !== 'POST' || !request.url.includes('/api/')) return;
event.respondWith((async () => {
// Kopie lesen, Original bleibt für fetch() unverbraucht
const kopie = request.clone();
try {
const body = await kopie.json();
console.log('Sende an API:', body);
} catch {
console.warn('Body ist kein JSON');
}
return fetch(request);
})());
});
Fehlerfall: Body doppelt lesen
const req = new Request('https://example.com', {
method: 'POST',
body: '{"a":1}'
});
await req.json();
try {
await req.json();
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Nur einmal lesbar: Der Körper ist ein Stream. Nach
json()istbodyUsedtrue; ein zweiter Lesevorgang wirftTypeError. Bei Bedarf vorherrequest.clone()verwenden – aber nicht nach dem Lesen, dann schlägt auchclone()fehl. - Content-Type wird nicht geprüft:
json()versucht immer zu parsen, unabhängig vom HeaderContent-Type. Prüfen Sie den Header selbst, wenn Sie strikt sein wollen. - Leerer Body: Ein leerer Körper (oder ein
GET-Request ohne Body) führt zu einemSyntaxError(„Unexpected end of JSON input“), nicht zunull. - Kodierung: Der Körper wird immer als UTF-8 dekodiert; ein angegebenes
charsetwird ignoriert. - Sicherheit: Geparste Daten stammen vom Client und sind nicht vertrauenswürdig. Validieren Sie Struktur und Typen (z. B. mit einem Schema), bevor Sie sie weiterverwenden, und begrenzen Sie serverseitig die Body-Größe, da
json()den gesamten Inhalt in den Speicher lädt. Vorsicht beim Zusammenführen in bestehende Objekte (Prototype Pollution über__proto__). - Kompatibilität: In allen modernen Browsern verfügbar; in Node.js global seit Version 18 (davor über
node-fetchoderundici).