Signatur
Beschreibung
Die Methode blob() gehört zum Body-Mixin, das von Request und Response implementiert wird. Sie liest den Stream des Anforderungstexts bis zum Ende und liefert die Daten als Blob. Der Blob übernimmt dabei als type den Wert des Content-Type-Headers der Anfrage (oder einen leeren String, wenn keiner gesetzt ist).
Gebraucht wird die Methode vor allem serverseitig bzw. in Service Workern: Dort kommen Anfragen als Request-Objekte an, etwa im fetch-Event oder in Laufzeitumgebungen wie Deno, Bun, Cloudflare Workers oder Node.js ab Version 18. Mit blob() kann man hochgeladene Binärdaten (Bilder, Dateien, PDFs) weiterverarbeiten, zwischenspeichern oder an eine andere Adresse weiterleiten.
Wichtig: Der Body ist ein Stream und lässt sich nur einmal lesen. Danach ist request.bodyUsed true, und jeder weitere Aufruf von blob(), text(), json() usw. schlägt mit einem TypeError fehl. Wer den Body mehrmals braucht, erzeugt vorher mit request.clone() eine Kopie.
Rückgabewert
Blob erfüllt wird, der den vollständigen Anforderungstext enthält. Hat die Anfrage keinen Body, ist der Blob leer (size = 0). Wurde der Body schon gelesen oder lässt sich der Stream nicht lesen, wird das Promise mit einem TypeError abgelehnt.Beispiele
Einfacher Fall: Request mit Binärdaten erzeugen und als Blob lesen
const bytes = new Uint8Array([72, 97, 108, 108, 111]); // "Hallo"
const request = new Request('https://example.com/upload', {
method: 'POST',
headers: { 'Content-Type': 'application/octet-stream' },
body: bytes
});
const blob = await request.blob();
console.log(blob.size, blob.type);
console.log(await blob.text());
Service Worker: hochgeladenes Bild abfangen und im Cache ablegen
self.addEventListener('fetch', (event) => {
const { request } = event;
if (request.method !== 'POST' || !request.url.endsWith('/avatar')) return;
event.respondWith((async () => {
// Kopie für das Netzwerk, Original für den lokalen Blob
const networkCopy = request.clone();
const image = await request.blob();
const cache = await caches.open('avatare');
await cache.put('/avatar-vorschau', new Response(image, {
headers: { 'Content-Type': image.type }
}));
return fetch(networkCopy);
})());
});
Server-Handler (Deno/Bun/Node 18+): Upload-Größe und Typ prüfen
const handleUpload = async (request) => {
const file = await request.blob();
if (!file.type.startsWith('image/')) {
return new Response('Nur Bilder erlaubt', { status: 415 });
}
if (file.size > 2 * 1024 * 1024) {
return new Response('Datei zu groß (max. 2 MB)', { status: 413 });
}
const buffer = await file.arrayBuffer();
return Response.json({ empfangen: buffer.byteLength, typ: file.type });
};
// Test
const req = new Request('http://localhost/upload', {
method: 'POST',
headers: { 'Content-Type': 'image/png' },
body: new Uint8Array(1024)
});
const res = await handleUpload(req);
console.log(await res.json());
Fallstrick: Body nur einmal lesbar
const request = new Request('/api', { method: 'POST', body: 'Daten' });
await request.blob();
console.log(request.bodyUsed);
try {
await request.blob();
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Einmal lesbar: Nach
blob()ist der Body verbraucht (bodyUsed === true). Für mehrfaches Lesen vorherrequest.clone()aufrufen – und zwar bevor irgendeine Lesemethode startet. - Speicherbedarf:
blob()puffert den gesamten Body. Bei sehr großen Uploads besser direkt mitrequest.body(einemReadableStream) arbeiten und die Daten stückweise verarbeiten. - MIME-Typ nicht vertrauen:
blob.typekommt aus dem vom Client gesendetenContent-Type-Header und lässt sich beliebig fälschen. Serverseitig bei Bedarf die Magic Bytes des Inhalts prüfen. - GET/HEAD: Diese Anfragen dürfen keinen Body haben;
blob()liefert dann einen leeren Blob. - Kompatibilität: In allen modernen Browsern (inkl. Service Worker) verfügbar, in Node.js ab Version 18 global (vorher über
undiciodernode-fetch). Fürmultipart/form-dataistrequest.formData()meist geeigneter.