Start · Sprachen · JavaScript · Referenz · new DecompressionStream()

new DecompressionStream()

Methode

Erstellt ein neues <code>DecompressionStream</code>-Objekt, das komprimierte Byte-Daten (gzip, deflate, deflate-raw) als Transform-Stream dekomprimiert.

seit JavaScript Baseline 2023: Chrome 80, Edge 80, Firefox 113, Sa Kategorie: webapi

Signatur

new DecompressionStream(format)

Beschreibung

Der Konstruktor DecompressionStream() erzeugt einen Transform-Stream. Er nimmt komprimierte Bytes entgegen und gibt die dekomprimierten Bytes wieder aus. Das Objekt hat eine writable-Seite (Eingabe) und eine readable-Seite (Ausgabe). Deshalb lässt es sich direkt mit ReadableStream.prototype.pipeThrough() in eine Stream-Kette einbauen.

Typische Anwendungsfälle sind gzip-komprimierte Dateien, die der Server ohne Content-Encoding-Header ausliefert (z. B. .json.gz-Dateien), vom Benutzer hochgeladene komprimierte Dateien, Daten aus IndexedDB und das Gegenstück zu einer vorherigen Kompression mit CompressionStream. Weil die Verarbeitung Stück für Stück läuft, muss die Eingabe nie vollständig im Speicher liegen. Das spart vor allem bei großen Dateien viel Speicher.

Unterstützt werden die Formate "gzip", "deflate" (zlib-Format nach RFC 1950) und "deflate-raw" (reines DEFLATE nach RFC 1951, ohne Header und Prüfsumme). Das Format muss zu den Eingabedaten passen. Ist es falsch oder sind die Daten beschädigt, bricht der Stream mit einem TypeError ab.

Parameter

Name Typ Default Beschreibung
$format Pflicht "gzip" | "deflate" | "deflate-raw" Das Kompressionsformat der Eingabedaten. Bei einem unbekannten Wert wirft der Konstruktor sofort einen TypeError. Neuere Implementierungen unterstützen teilweise auch "brotli"; darauf sollte man sich aber noch nicht verlassen.

Rückgabewert

Typ
DecompressionStream
Beschreibung
Ein neues DecompressionStream-Objekt mit den Eigenschaften readable (ReadableStream<Uint8Array>) und writable (WritableStream<BufferSource>).

Beispiele

Gzip-komprimiertes JSON per fetch laden und entpacken

const loadGzipJson = async (url) => {
  const response = await fetch(url);
  if (!response.ok) throw new Error(`HTTP ${response.status}`);

  // Komprimierten Body durch den DecompressionStream leiten
  const stream = response.body.pipeThrough(new DecompressionStream('gzip'));

  // Response-Wrapper, um bequem .json() nutzen zu können
  return new Response(stream).json();
};

const data = await loadGzipJson('/daten/produkte.json.gz');
console.log(`${data.length} Produkte geladen`);
1250 Produkte geladen

Roundtrip: Text komprimieren und wieder dekomprimieren

const text = 'Hallo Welt! '.repeat(1000);

// Komprimieren
const compressed = await new Response(
  new Blob([text]).stream().pipeThrough(new CompressionStream('deflate'))
).arrayBuffer();

// Dekomprimieren
const restored = await new Response(
  new Blob([compressed]).stream().pipeThrough(new DecompressionStream('deflate'))
).text();

console.log(text.length, '→', compressed.byteLength, 'Bytes');
console.log(restored === text);
12000 → 60 Bytes true

Hochgeladene .gz-Datei zeilenweise verarbeiten mit Fehlerbehandlung

const input = document.querySelector('#datei');

input.addEventListener('change', async () => {
  const file = input.files[0];
  if (!file) return;

  try {
    const lines = file.stream()
      .pipeThrough(new DecompressionStream('gzip'))
      .pipeThrough(new TextDecoderStream());

    let bytes = 0;
    for await (const chunk of lines) {
      bytes += chunk.length;
    }
    console.log(`Entpackt: ${bytes} Zeichen`);
  } catch (err) {
    // Falsches Format oder beschädigte Daten
    console.error('Dekompression fehlgeschlagen:', err.name);
  }
});
Entpackt: 482113 Zeichen

// Wichtig · Fallstricke

  • Nicht doppelt dekomprimieren: Liefert der Server die Daten mit Content-Encoding: gzip aus, entpackt der Browser sie bereits automatisch. Wer dann zusätzlich einen DecompressionStream einsetzt, bekommt einen TypeError. Der Stream ist nur für Daten gedacht, die als rohe Bytes ankommen (z. B. Content-Type: application/gzip).
  • Fehler treten asynchron auf: Ein ungültiges format führt schon im Konstruktor zu einem TypeError. Beschädigte Daten, ein falsches Format oder unvollständige Daten am Ende (abgeschnittener Stream) fallen dagegen erst beim Lesen auf, als abgelehntes Promise bzw. abgebrochener Stream.
  • Formate unterscheiden: "deflate" erwartet einen zlib-Header. Rohe DEFLATE-Daten, etwa aus ZIP-Einträgen, brauchen "deflate-raw". ZIP-Archive selbst werden nicht unterstützt, dafür braucht man eine Bibliothek.
  • Sicherheit: Vorsicht bei „Dekompressionsbomben“: Winzige Eingaben können sich auf Gigabytes aufblähen. Bei fremden Daten sollte man die Ausgabemenge beim Lesen zählen und den Stream bei Überschreitung eines Limits mit reader.cancel() abbrechen.
  • Kompatibilität: "deflate-raw" und die Unterstützung in Firefox und Safari gibt es erst seit 2023. Mit typeof DecompressionStream !== 'undefined' prüfen, ob die API vorhanden ist, und sonst z. B. auf pako ausweichen. In Node.js ist die API ab Version 18 global verfügbar. Sie funktioniert auch in Web Workern.