Signatur
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
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`);
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);
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);
}
});
// Wichtig · Fallstricke
- Nicht doppelt dekomprimieren: Liefert der Server die Daten mit
Content-Encoding: gzipaus, entpackt der Browser sie bereits automatisch. Wer dann zusätzlich einenDecompressionStreameinsetzt, bekommt einenTypeError. 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
formatführt schon im Konstruktor zu einemTypeError. 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. Mittypeof 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.