Signatur
Beschreibung
Die Methode arrayBuffer() gehört zum Body-Mixin, das sowohl Request als auch Response implementieren. Sie liest den Datenstrom des Anforderungskörpers bis zum Ende und liefert die Bytes als ArrayBuffer, also als Binärdaten ohne jede Interpretation als Text oder JSON.
Praktisch einsetzen lässt sie sich vor allem dort, wo man eingehende Anfragen selbst verarbeitet: in einem Service Worker (fetch-Event), in Edge-/Serverless-Umgebungen wie Cloudflare Workers, Deno oder Bun, und in Node.js-Frameworks, die die Fetch-API nutzen. Typische Anwendungsfälle sind das Prüfen von Signaturen (HMAC über den Rohkörper), das Berechnen von Hashwerten, das Weiterreichen hochgeladener Dateien oder das Parsen binärer Formate mit DataView bzw. typisierten Arrays.
Der Körper eines Requests lässt sich nur einmal lesen. Nach dem Aufruf ist request.bodyUsed gleich true, und jeder weitere Aufruf einer Lesemethode (text(), json(), blob() usw.) schlägt mit einem TypeError fehl. Wenn die Daten mehrfach gebraucht werden, legt man vorher mit request.clone() eine Kopie an.
Rückgabewert
ArrayBuffer mit dem vollständigen Anforderungskörper erfüllt wird. Hat der Request keinen Körper (z. B. bei GET), ist der Puffer leer (byteLength === 0). Das Promise wird mit einem TypeError abgelehnt, wenn der Körper schon gelesen wurde oder der Datenstrom gesperrt ist, und mit einer AbortError-DOMException, wenn die Anfrage abgebrochen wird.Beispiele
Rohdaten eines selbst erstellten Requests auslesen
const request = new Request('https://example.com/upload', {
method: 'POST',
body: new Uint8Array([72, 97, 108, 108, 111])
});
const buffer = await request.arrayBuffer();
console.log(buffer.byteLength);
console.log(new TextDecoder().decode(buffer));
console.log(request.bodyUsed);
SHA-256-Prüfsumme des Upload-Körpers im Service Worker
self.addEventListener('fetch', (event) => {
if (event.request.method !== 'POST') return;
event.respondWith((async () => {
// Kopie anlegen, damit der Original-Request weitergeleitet werden kann
const copy = event.request.clone();
const data = await copy.arrayBuffer();
const hash = await crypto.subtle.digest('SHA-256', data);
const hex = [...new Uint8Array(hash)]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
console.log('Upload-Hash:', hex);
return fetch(event.request);
})());
});
Webhook-Signatur (HMAC) in einem Edge-Handler prüfen
const verifyWebhook = async (request, secret) => {
const signatureHex = request.headers.get('X-Signature') ?? '';
const body = await request.arrayBuffer();
const key = await crypto.subtle.importKey(
'raw',
new TextEncoder().encode(secret),
{ name: 'HMAC', hash: 'SHA-256' },
false,
['verify']
);
const signature = Uint8Array.from(
signatureHex.match(/.{2}/g) ?? [],
(h) => parseInt(h, 16)
);
const valid = await crypto.subtle.verify('HMAC', key, signature, body);
// Nach erfolgreicher Prüfung den Rohkörper selbst als JSON parsen
return valid ? JSON.parse(new TextDecoder().decode(body)) : null;
};
export default {
async fetch(request) {
const payload = await verifyWebhook(request, 'mein-geheimnis');
return payload
? new Response('OK')
: new Response('Ungültige Signatur', { status: 401 });
}
};
Doppeltes Lesen vermeiden
const request = new Request('/api', { method: 'POST', body: 'Daten' });
await request.arrayBuffer();
try {
await request.text();
} catch (err) {
console.log(err.name);
}
// Wichtig · Fallstricke
- Nur einmal lesbar: Nach
arrayBuffer()ist der Körper aufgebraucht (bodyUsed === true). Vor dem Lesenrequest.clone()aufrufen, wenn der Request danach noch mitfetch()weitergereicht oder erneut gelesen werden soll. - Speicherbedarf: Der gesamte Körper wird in den Arbeitsspeicher geladen. Bei großen Uploads besser direkt über
request.body(einenReadableStream) stückweise verarbeiten. - Signaturprüfung: Für HMAC-Prüfungen immer den Rohkörper verwenden, nicht erst
json()aufrufen und dann neu serialisieren, denn schon kleine Unterschiede bei Leerzeichen oder der Reihenfolge der Schlüssel machen die Signatur ungültig. - Ohne Körper (z. B. bei
GET/HEAD) wird ein leererArrayBuffergeliefert, es gibt keinen Fehler. - Neuere Umgebungen bieten zusätzlich
request.bytes(), das direkt einUint8Arrayliefert. Die Unterstützung dafür ist aber noch nicht überall vorhanden.arrayBuffer()wird dagegen in allen modernen Browsern, Node.js 18+ und Deno unterstützt, im Internet Explorer nicht.