Signatur
Beschreibung
Die Methode text() gehört zum Body-Mixin, das von Request (und Response) implementiert wird. Sie liest den Datenstrom (ReadableStream) des Anfragekörpers bis zum Ende aus und dekodiert die Bytes immer als UTF-8. Ein im Content-Type angegebenes charset wird dabei nicht berücksichtigt.
Typische Einsatzorte sind Service Worker (im fetch-Event eine ausgehende Anfrage prüfen, protokollieren oder verändern), serverseitige Laufzeitumgebungen mit Fetch-API wie Node.js, Deno, Bun oder Cloudflare Workers, wo eingehende HTTP-Anfragen als Request ankommen, und Tests, in denen man den Körper einer selbst gebauten Anfrage kontrollieren will.
Der Körper lässt sich nur ein einziges Mal lesen. Danach steht request.bodyUsed auf true, und jeder weitere Aufruf von text(), json(), blob() usw. wird mit einem TypeError abgelehnt. Wer den Körper mehrfach braucht, zum Beispiel um ihn zu protokollieren und danach weiterzuleiten, muss vorher request.clone() aufrufen.
Rückgabewert
GET), ist der String leer (""). Das Promise wird mit einem TypeError abgelehnt, wenn der Körper schon gelesen wurde oder der Datenstrom gesperrt bzw. abgebrochen ist.Beispiele
Körper einer selbst erstellten Anfrage lesen
const request = new Request('https://example.com/api/notes', {
method: 'POST',
headers: { 'Content-Type': 'text/plain' },
body: 'Einkaufsliste: Milch, Brot'
});
const text = await request.text();
console.log(text);
console.log(request.bodyUsed);
Service Worker: POST-Körper protokollieren und die Anfrage trotzdem weiterleiten
// sw.js
self.addEventListener('fetch', (event) => {
const { request } = event;
if (request.method !== 'POST') return;
event.respondWith((async () => {
// Kopie lesen, damit das Original unverbraucht bleibt
const body = await request.clone().text();
console.log(`[SW] POST ${request.url} (${body.length} Zeichen)`);
return fetch(request);
})());
});
Serverseitig (Deno / Bun / Cloudflare Workers): Webhook-Signatur über den Rohtext prüfen
export default {
async fetch(request) {
// Für die HMAC-Prüfung wird der unveränderte Rohtext gebraucht
const raw = await request.text();
const signature = request.headers.get('X-Signature') ?? '';
const key = await crypto.subtle.importKey(
'raw', new TextEncoder().encode('geheim'),
{ name: 'HMAC', hash: 'SHA-256' }, false, ['sign']
);
const mac = await crypto.subtle.sign('HMAC', key, new TextEncoder().encode(raw));
const hex = [...new Uint8Array(mac)].map((b) => b.toString(16).padStart(2, '0')).join('');
if (hex !== signature) return new Response('Ungültige Signatur', { status: 401 });
const payload = JSON.parse(raw);
return new Response(`Ereignis ${payload.type} empfangen`);
}
};
Fehler bei doppeltem Lesen abfangen
const req = new Request('https://example.com', { method: 'POST', body: 'Hallo' });
await req.text();
try {
await req.text(); // zweiter Leseversuch
} catch (err) {
console.log(err.name, '-', req.bodyUsed);
}
// Wichtig · Fallstricke
- Nur einmal lesbar: Nach
text()ist der Körper verbraucht (bodyUsed === true).clone()muss vor dem Lesen aufgerufen werden, danach wirft auchclone()einenTypeError. - Immer UTF-8: Eine andere Zeichenkodierung im
Content-Type(z. B.ISO-8859-1) wird ignoriert. Für andere Kodierungen den Körper mitarrayBuffer()lesen und mitnew TextDecoder('iso-8859-1')dekodieren. - Binärdaten: Bei Bildern, Dateien oder Protobuf-Daten verfälscht
text()den Inhalt, weil ungültige Bytefolgen durch U+FFFD ersetzt werden. HierarrayBuffer(),blob()oderbytes()verwenden. - Speicher und Missbrauch: Der gesamte Körper wird in den Speicher geladen. Auf Servern vorher
Content-Lengthprüfen oder den Datenstrom mit Größenlimit überrequest.bodylesen, um Denial-of-Service durch sehr große Anfragen zu verhindern. - Nicht vertrauenswürdige Eingaben: Den gelesenen Text nie ungeprüft in
innerHTML,eval()oder SQL-Abfragen einsetzen (Gefahr von XSS bzw. Injection). - Kompatibilität: Wird von allen modernen Browsern unterstützt, auch in Service Workern. In Node.js steht die Methode ab Version 18 global bereit (vorher über
undiciodernode-fetch).