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

Response.arrayBuffer()

Methode

Liest den Body-Stream einer <code>Response</code> vollständig aus und liefert ein Promise, das mit den Rohdaten als <code>ArrayBuffer</code> erfüllt wird.

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

Signatur

Response.prototype.arrayBuffer()

Beschreibung

Die Methode arrayBuffer() des Response-Interfaces liest den Body-Stream einer HTTP-Antwort bis zum Ende und stellt den Inhalt als ArrayBuffer bereit, also als rohe Binärdaten mit fester Länge. Anders als bei text() oder json() wird der Inhalt dabei weder dekodiert noch interpretiert.

Die Methode eignet sich immer dann, wenn man Binärdaten Byte für Byte verarbeiten will: Audiodateien für die Web Audio API (AudioContext.decodeAudioData()), WebAssembly-Module, Bilder zur Pixelanalyse, eigene Binärformate, Prüfsummen mit crypto.subtle.digest() oder das Weiterreichen an Worker per Transfer. Um auf die Daten zuzugreifen, legt man eine Sicht darauf an, zum Beispiel ein Uint8Array oder eine DataView.

Der Body lässt sich nur einmal lesen. Nach dem Aufruf ist response.bodyUsed gleich true, und jeder weitere Aufruf einer Body-Methode (text(), json(), blob() …) schlägt fehl. Braucht man die Daten mehrfach, legt man vorher mit response.clone() eine Kopie an.

Rückgabewert

Typ
Promise<ArrayBuffer>
Beschreibung
Ein Promise, das mit einem ArrayBuffer erfüllt wird, der den kompletten Body enthält. Es wird mit einem TypeError abgelehnt, wenn der Body schon gelesen wurde oder der Stream nicht gelesen werden kann, und mit einem AbortError (DOMException), wenn der Request abgebrochen wurde.

Beispiele

Datei laden und Größe sowie erste Bytes prüfen

const ladeBinaer = async (url) => {
  const response = await fetch(url);
  if (!response.ok) {
    throw new Error(`HTTP-Fehler: ${response.status}`);
  }
  const buffer = await response.arrayBuffer();
  const bytes = new Uint8Array(buffer);
  console.log(`Größe: ${buffer.byteLength} Bytes`);
  // PNG-Signatur prüfen: 89 50 4E 47
  const istPng = bytes[0] === 0x89 && bytes[1] === 0x50 && bytes[2] === 0x4e && bytes[3] === 0x47;
  console.log('PNG?', istPng);
};

ladeBinaer('/bilder/logo.png');
Größe: 15342 Bytes PNG? true

Audiodatei für die Web Audio API dekodieren

const ctx = new AudioContext();

const spieleSound = async (url) => {
  const response = await fetch(url);
  const buffer = await response.arrayBuffer();
  const audioBuffer = await ctx.decodeAudioData(buffer);
  const quelle = ctx.createBufferSource();
  quelle.buffer = audioBuffer;
  quelle.connect(ctx.destination);
  quelle.start();
  console.log(`Dauer: ${audioBuffer.duration.toFixed(2)} s`);
};

document.querySelector('#play').addEventListener('click', () => spieleSound('/sounds/klick.mp3'));
Dauer: 0.35 s

SHA-256-Prüfsumme eines Downloads berechnen

const sha256 = async (url) => {
  const response = await fetch(url);
  const daten = await response.arrayBuffer();
  const hash = await crypto.subtle.digest('SHA-256', daten);
  return [...new Uint8Array(hash)]
    .map((b) => b.toString(16).padStart(2, '0'))
    .join('');
};

sha256('/downloads/setup.zip').then((h) => console.log('SHA-256:', h));
SHA-256: 3a7bd3e2360a3d29eea436fcfb7e44c735d117c42d1c1835420b6b9942dd4f1b

Body mehrfach nutzen mit clone()

const response = await fetch('/api/daten.bin');
const kopie = response.clone();

const buffer = await response.arrayBuffer();
const blob = await kopie.blob();

console.log(buffer.byteLength === blob.size);
console.log(response.bodyUsed);
true true

// Wichtig · Fallstricke

  • Nur einmal lesbar: Ein zweiter Aufruf (auch mit text(), json() usw.) wirft TypeError: body stream already read. Wer die Daten öfter braucht, ruft vorher response.clone() auf.
  • HTTP-Fehler prüfen: fetch() lehnt bei 404 oder 500 nicht ab. Ohne Prüfung von response.ok landet sonst eine Fehlerseite als Binärdaten im Buffer.
  • Speicherbedarf: Die ganze Antwort wird in den Arbeitsspeicher geladen. Bei sehr großen Dateien ist es besser, response.body als ReadableStream Stück für Stück zu lesen, zumal man dann auch einen Fortschritt anzeigen kann.
  • CORS: Bei opaque-Antworten (mode: 'no-cors') ist der Body leer, und der Buffer hat die Länge 0.
  • Text dekodieren: Für Text mit einer anderen Kodierung als UTF-8 kombiniert man arrayBuffer() mit new TextDecoder('iso-8859-1').decode(buffer), denn text() dekodiert immer als UTF-8.
  • Kompatibilität: Wird von allen modernen Browsern und von Node.js ab Version 18 (natives fetch) unterstützt. Neuere Umgebungen bieten zusätzlich Response.bytes(), das direkt ein Uint8Array liefert.