Start · Sprachen · JavaScript · Referenz · Request.arrayBuffer()

Request.arrayBuffer()

Methode

Liest den Körper eines <code>Request</code>-Objekts vollständig aus und gibt ein Promise zurück, das mit den Rohdaten als <code>ArrayBuffer</code> erfüllt wird.

seit JavaScript Baseline: alle modernen Browser (seit 2017), Node. Kategorie: webapi

Signatur

Request.prototype.arrayBuffer()

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

Typ
Promise<ArrayBuffer>
Beschreibung
Ein Promise, das mit einem 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);
5 Hallo true

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);
  })());
});
Upload-Hash: 9f86d081884c7d65... (abhängig vom Inhalt)

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);
}
TypeError

// Wichtig · Fallstricke

  • Nur einmal lesbar: Nach arrayBuffer() ist der Körper aufgebraucht (bodyUsed === true). Vor dem Lesen request.clone() aufrufen, wenn der Request danach noch mit fetch() 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 (einen ReadableStream) 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 leerer ArrayBuffer geliefert, es gibt keinen Fehler.
  • Neuere Umgebungen bieten zusätzlich request.bytes(), das direkt ein Uint8Array liefert. 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.