Signatur
Beschreibung
Die Eigenschaft bodyUsed gehört zum Body-Mixin, das von Request und Response gemeinsam genutzt wird. Sie ist true, sobald der Anfrageinhalt über eine der Lesemethoden wie text(), json(), formData(), blob(), arrayBuffer() oder bytes() gelesen wurde. Das gilt auch, wenn der Inhalt direkt über den body-Stream gelesen wurde oder wenn der Request an fetch() übergeben wurde.
Ein Request-Body ist ein Stream und lässt sich deshalb nur einmal lesen. Mit bodyUsed kannst du vor dem Lesen prüfen, ob das noch geht. So vermeidest du einen TypeError („body stream already read“). Das ist besonders in Service Workern, in Middleware-Ketten und in Retry-Logik wichtig, wo mehrere Codeteile auf dasselbe Request-Objekt zugreifen.
Wenn der Inhalt mehrfach gebraucht wird, erzeugst du vor dem ersten Lesen mit request.clone() eine Kopie. Hat ein Request gar keinen Body (z. B. bei GET), bleibt bodyUsed immer false.
Rückgabewert
true, wenn der Body bereits gelesen wurde, sonst false.Beispiele
Status vor und nach dem Lesen prüfen
const request = new Request('https://example.com/api', {
method: 'POST',
body: JSON.stringify({ name: 'Anna' }),
headers: { 'Content-Type': 'application/json' }
});
console.log(request.bodyUsed);
const data = await request.json();
console.log(data.name);
console.log(request.bodyUsed);
Doppeltes Lesen verhindern
const request = new Request('https://example.com/log', {
method: 'POST',
body: 'Hallo Welt'
});
const readBodySafe = async (req) => {
if (req.bodyUsed) {
console.warn('Body wurde bereits gelesen.');
return null;
}
return req.text();
};
console.log(await readBodySafe(request));
console.log(await readBodySafe(request));
Service Worker: mit clone() loggen und weiterleiten
self.addEventListener('fetch', (event) => {
if (event.request.method !== 'POST') return;
event.respondWith((async () => {
// Kopie vor dem Lesen erzeugen
const kopie = event.request.clone();
const inhalt = await kopie.text();
console.log('Gesendet:', inhalt, '| Kopie gelesen:', kopie.bodyUsed);
console.log('Original noch lesbar:', !event.request.bodyUsed);
return fetch(event.request);
})());
});
Retry-Logik: fetch() konsumiert den Body
const original = new Request('https://example.com/upload', {
method: 'POST',
body: 'Daten'
});
const sendMitRetry = async (req, versuche = 2) => {
for (let i = 0; i < versuche; i++) {
const kopie = req.clone(); // für jeden Versuch eine frische Kopie
try {
return await fetch(kopie);
} catch (err) {
console.log(`Versuch ${i + 1} fehlgeschlagen, Kopie verbraucht: ${kopie.bodyUsed}`);
}
}
throw new Error('Alle Versuche fehlgeschlagen');
};
await sendMitRetry(original).catch(console.error);
// Wichtig · Fallstricke
- Nur einmal lesbar: Wenn
bodyUsedtrueist, wirft jeder weitere Aufruf vontext(),json()usw. einenTypeError. Dieser Fehler kommt als abgelehnter Promise. clone()rechtzeitig aufrufen:request.clone()wirft ebenfalls einenTypeError, wenn der Body schon gelesen wurde. Die Kopie muss also vor dem ersten Lesen entstehen.fetch()konsumiert den Body: Nachfetch(request)ist der Body des übergebenen Requests verbraucht. Für einen erneuten Versuch brauchst du eine Kopie.- Sperre durch einen Reader: Schon ein über
request.body.getReader()gesperrter Stream macht weitere Lesemethoden unmöglich.bodyUsedwird dabei möglicherweise erst nach dem eigentlichen Lesentrue. Zusätzlich hilftrequest.body?.locked. - Anfragen ohne Body: Bei
GET/HEADoder fehlendem Body bleibt der Wert immerfalse. - Speicherbedarf:
clone()puffert Daten intern (Tee-Stream). Große Uploads zu klonen kann deshalb viel Speicher kosten. - Kompatibilität: Wird von allen modernen Browsern, in Web- und Service Workern sowie in Node.js ab Version 18 (natives
fetch) unterstützt.