Start · Sprachen · JavaScript · Referenz · Blob.slice()

Blob.slice()

Methode

Erzeugt ein neues <code>Blob</code>, das einen Byte-Ausschnitt des ursprünglichen Blobs enthält, ohne die Daten sofort zu kopieren.

seit JavaScript Baseline: alle Browser (seit 2015), Node.js 15.7+ Kategorie: webapi

Signatur

Blob.prototype.slice(start, end, contentType)

Beschreibung

slice() gibt ein neues Blob-Objekt zurück, das die Bytes vom Index start (einschließlich) bis end (ausschließlich) des Quell-Blobs enthält. Das Original bleibt unverändert. Da File von Blob erbt, funktioniert die Methode auch direkt auf Dateien aus einem <input type="file"> oder aus Drag-and-Drop.

Typische Einsatzfälle sind Chunked Uploads (große Dateien in Teilen hochladen, Uploads fortsetzen), das Lesen von Datei-Headern (z. B. Magic Bytes zur Erkennung des Dateityps) und das Verarbeiten großer Dateien in Stücken, damit nicht alles auf einmal im Speicher liegt.

Die Indizes zählen Bytes, nicht Zeichen. Negative Werte werden vom Ende des Blobs aus gezählt, ähnlich wie bei Array.prototype.slice(). Werte außerhalb des gültigen Bereichs werden auf 0 bzw. size begrenzt. Browser erzeugen den Ausschnitt in der Regel als Referenz auf die Originaldaten, das Aufrufen von slice() ist daher sehr günstig. Gelesen wird erst über text(), arrayBuffer(), stream() oder FileReader.

Parameter

Name Typ Default Beschreibung
$start number 0 Byte-Index, an dem der Ausschnitt beginnt (einschließlich). Negative Werte zählen vom Ende. Ein Wert größer als size ergibt ein leeres Blob.
$end number blob.size Byte-Index, an dem der Ausschnitt endet (ausschließlich). Negative Werte zählen vom Ende.
$contentType string "" MIME-Typ für das neue Blob, z. B. "text/plain". Ohne Angabe ist type ein leerer String und wird nicht vom Original übernommen.

Beispiele

Grundlagen: Ausschnitte mit positiven und negativen Indizes

const blob = new Blob(['Hallo Welt!'], { type: 'text/plain' });

const anfang = blob.slice(0, 5);
const ende = blob.slice(-6); // letzte 6 Bytes
const typisiert = blob.slice(6, 10, 'text/plain');

console.log(await anfang.text());
console.log(await ende.text());
console.log(anfang.type === '', typisiert.type);
Hallo Welt! true text/plain

Dateityp über Magic Bytes erkennen

const input = document.querySelector('input[type="file"]');

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

  // Nur die ersten 4 Bytes lesen – nicht die ganze Datei
  const header = new Uint8Array(await file.slice(0, 4).arrayBuffer());
  const hex = [...header].map((b) => b.toString(16).padStart(2, '0')).join('');

  const typen = { '89504e47': 'PNG', '25504446': 'PDF', '504b0304': 'ZIP' };
  console.log(typen[hex] ?? `Unbekannt (${hex})`);
});
PNG

Große Datei in Chunks hochladen

const uploadInChunks = async (file, url, chunkSize = 5 * 1024 * 1024) => {
  for (let offset = 0; offset < file.size; offset += chunkSize) {
    const chunk = file.slice(offset, offset + chunkSize);
    const endByte = offset + chunk.size - 1;

    const res = await fetch(url, {
      method: 'PUT',
      headers: {
        'Content-Range': `bytes ${offset}-${endByte}/${file.size}`
      },
      body: chunk
    });
    if (!res.ok) throw new Error(`Chunk ab Byte ${offset} fehlgeschlagen`);
    console.log(`${Math.round(((endByte + 1) / file.size) * 100)} %`);
  }
};

// Aufruf: await uploadInChunks(input.files[0], '/api/upload');
42 % 85 % 100 %

// Wichtig · Fallstricke

  • Bytes statt Zeichen: Bei UTF-8-Text können Mehrbyte-Zeichen (Umlaute, Emojis) mitten durchgeschnitten werden. text() ersetzt die kaputten Bytes dann durch �. Zum Stückweise-Dekodieren besser TextDecoder mit { stream: true } oder blob.stream().pipeThrough(new TextDecoderStream()) verwenden.
  • end ist exklusiv: slice(0, 4) liefert die Bytes 0 bis 3. Beim HTTP-Header Content-Range ist das Ende dagegen inklusiv, also -1 nicht vergessen.
  • MIME-Typ geht verloren: Ohne drittes Argument ist type leer. Wer ihn braucht, übergibt blob.type ausdrücklich.
  • Veraltete Präfixe: webkitSlice() und mozSlice() sind überholt. Sehr alte Implementierungen erwarteten (start, length) statt (start, end).
  • Speicher: Ein Ausschnitt kann die Daten des Originals weiter im Speicher halten. Ein kleiner Slice eines großen Blobs verhindert unter Umständen, dass der Speicher des großen Blobs freigegeben wird.
  • In Node.js ist Blob seit Version 15.7 verfügbar und seit 18 global.