SELF-Treffen in Mannheim 2025

SELFHTML wird 30 Jahre alt! → Veranstaltungs-Ankündigung.

JavaScript/Blob

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Ein Blob ist ein JavaScript-Objekt, das eine Bytefolge beliebiger Länge enthalten kann. Es besitzt eine size-Eigenschaft, die die Anzahl der gespeicherten Bytes angibt, und eine type-Eigenschaft, die die Art des Blob-Inhalts als MIME-Type angibt. Der type kann auch leer sein, wenn kein Typ angegeben werden kann, oder auch application/octet-stream, wenn es eine Bytefolge ist, für die es keinen expliziten MIME-Typ gibt.

Ein Blob kann der Rückgabewert von anderen APIs sein (z. B. können Sie im Fetch-API die Server-Antwort als Blob erhalten), und einige APIs erwarten oder akzeptieren Blobs als Eingabe (z. B. createObjectURL). Sie können Blobs selbst erzeugen und ihren Inhalt auf unterschiedliche Weise auslesen.

Erstellen eines Blobs

Blobs sind JavaScript-Objekte und können mit der Konstruktorfunktion Blob erstellt werden.

Konstruktor

const blob = new Blob(inhalt, options);

inhalt
Ein Array mit Daten, die als Bytefolge hintereinander in den Blob geschrieben werden sollen. Ein Array-Eintrag kann sein
  • Ein String - er wird UTF-8 codiert und die entstehenden Bytes werden in den Blob übernommen
  • Ein Blob - die darin gespeicherten Bytes werden in den Blob übernommen
  • Ein Arraybuffer - die Bytes des Arraybuffers werden in den Blob übernommen
  • Ein Typed Array oder ein DataView - der zu Grunde liegende Arraybuffer wird in den Blob übernommen
options
Ein Objekt, das zwei Eigenschaften aufweisen kann:
type (optional)
Der MIME-Typ des Blob-Inhalts. Der Defaultwert ist ein leerer String.
endings (optional)
Entweder "transparent" oder "native". Gibt an, ob Zeilenendezeichen in Strings, die in den Blob eingesetzt werden, unverändert bleiben oder eine Umwandlung in die Zeilenendezeichen des Betriebssystems erfolgt, unter dem das Script ausgeführt wird. Gebräuchliche Zeilenendezeichen sind das Zeichen CR (carriage return, Zeichencode 0x0d) und das Zeichen LF (line feed, Zeichencode 0x0a). Unix und aktuelle Mac-Betriebssysteme verwenden LF als Zeilenende, Windows hingegen die Zeichenfolge CR LF. Mac OS Classic verwendete CR. Wenn Sie "native" angeben, wird ein String, der im Blob gespeichert werden soll, nach Zeilenenden in diesen drei Formaten durchsucht, und jedes Zeilende durch das Zeilenende ersetzt, das für System üblich ist, auf dem der Blob erstellt wird.
Beachten Sie: Ein <input type="file">-Element besitzt die files-Eigenschaft, worin Sie eine FileList finden, die die ausgewählten Dateien als File-Objekte bereitstellt. File-Objekte sind von Blob abgeleitet, die folgenden Beschreibungen gelten deshalb auch für sie.

Anwendungsbeispiel: Bereitstellen eines Download-Links für einen Textblock

Ein Blob kann als Argument für URL.createObjectURL verwendet werden. Die daraus entstehende URL kann in das href-Attribut eines a-Elements eingesetzt werden, um auf diese Weise den Download des Blob-Inhalts möglich zu machen. So etwas ist dann sinnvoll, wenn der Blob-Inhalt nicht aus einer Serverdatei stammt, sondern vom Script erstellt wurde. Für einen solchen Download-Link setzt man außer dem href- auch das download-Attribut. Dadurch wird zum einen ein Dateiname für den Download vorgegeben, und man verhindert, dass der Browser das Linkziel einfach nur anzeigt.

Es ist auch möglich, den Download automatisch zu starten. Dafür ruft man auf dem Elementobjekt des a-Elements die click-Methode auf. Aus Sicherheitsgründen reagieren Browser aber darauf zumeist mit einer Rückfrage. Die im folgende Beispiel gezeigte write_file-Funktion verwendet diese Methode: Ein Datenblock wird in einem Blob mit MIME-Typ 'text/plain' gespeichert. Daraus wird ein Download-Link nach dem Muster <a download="xxx.txt" href="..."></a> erzeugt, am Ende des Dokuments angefügt, ein Klick darauf ausgelöst und das Element sofort wieder entfernt

Download eines Datenblocks
// data: Text-Daten, die als Download bereitzustellen sind
// dateiname: Name, unter dem die Datei downgeloadet wird
function write_file(data, dateiname) {
	const blob = new Blob([data], {type:'text/plain'}),
	      link = document.createElement("a");
	a.download = dateiname;
	a.href = URL.createObjectURL(blob);
	document.body.append(a);
	a.click();
	a.remove(a);
}

(Beispiel basiert auf einer Vorlage von JürgenB im Selfhtml-Forum)

Methoden eines Blob-Objekts

Außer den zu Anfang erwähnten Eigenschaften size und type besitzen Blob-Objekte noch Methoden, um ihren Inhalt auszulesen.

slice()

Wenn Sie nicht auf den ganzen Inhalt eines Blobs zugreifen möchten, sondern nur auf einen Teil davon, können Sie mit der slice-Methode einen Teil des Blobs herauskopieren und daraus einen neuen Blob erstellen, der dann mit einer der übrigen Methoden ausgelesen werden kann.

slice kann in einer von vier Varianten aufgerufen werden:

newBlob = blob.slice();
Kopieren des gesamten Blobinhalts
newBlob = blob.slice(start);
Kopieren des Blobinhalts von einer Startposition bis zum Ende
newBlob = blob.slice(start, ende);
Kopieren des Blobinhalts von einer Startposition bis zu einer Endposition
newBlob = blob.slice(start, ende, typ);
Kopieren des Blobinhalts und Festlegen eines MIME-Typs für den neu erstellten Blob.
start
Position im Blob, ab der kopiert werden soll. Das erste Byte im Blob hat die Position 0.
Negative Werte sind erlaubt, dadurch wird die Startposition vom Ende des Blobs her berechnet
ende
Position im Blob, ab der nicht mehr kopiert werden soll. ende - start ergibt also die Anzahl der kopierten Bytes.
Wird kein Ende angegeben, wird ende auf den Wert der size-Eigenschaft des Blobs gesetzt.
Negative Werte sind erlaubt, dadurch wird die Endposition vom Ende des Blobs her berechnet. Beachten Sie, dass -0 nicht dazu führt, dass bis zum Blob-Ende kopiert wird! Um bis zum Blob-Ende zu kopieren, müssen Sie blob.size als Endposition angeben.
typ
Der MIME-Typ für die erstellte Kopie. Fehlt dieser Parameter, hat der neue Blob den leeren String als Typ, d. h. es wird nicht der Typ der Kopierquelle übernommen.

arrayBuffer()

Blobs sind nicht transferierbar, d. h. man kann einen Blob nicht an einen Web Worker übergeben oder von ihm erhalten. Man kann auch nicht direkt auf seinen Inhalt zugreifen. Mit der arrayBuffer() Methode lässt sich der Blob-Inhalt als ArrayBuffer auslesen. ArrayBuffer sind transferierbar, und man kann sie als Datenbasis eines DataView oder eines TypedArray verwenden, um auf den Inhalt zuzugreifen.

Die arrayBuffer() hat keine Parameter. Sie kann bei großen Blobs Zeit benötigen und liefert deshalb nicht direkt den ArrayBuffer, sondern ein Promise, das mit dem ArrayBuffer erfüllt wird.

Blob in ArrayBuffer kopieren
blob.arrayBuffer()
.then(function(buf) {
   // ArrayBuffer verwenden
})
.catch(function(error) {
   // Errorhandling. arrayBuffer() kann Fehler auslösen, der then-Handler möglicherweise auch.
});

bytes()

Möchte man auf die Daten eines Blobs byteweise zugreifen, ist es hilfreich, ihn in ein TypedArray vom Typ Uint8Array zu übertragen. Die bytes()-Methode tut genau das. Sie erwartet keine Parameter und gibt ein Promise zurück, das mit einem Uint8Array erfüllt wird.

Es handelt sich aber lediglich um eine Bequemlichkeitsmethode, die Sie in 2 Zeilen selbst programmieren können:

Blob in Uint8Array kopieren
function blob_to_bytes(blob) {
   return blob.arrayBuffer()
          .then(buf => new Uint8Array(buffer));
}

text()

Wenn ein Blob einen als UTF-8 codierten Text enthält, lässt er sich mit der text()-Methode in einen JavaScript-String umwandeln. Die text()-Methode erwartet keine Parameter und gibt ein Promise zurück, das mit der String-Darstellung des Blob-Inhalts erfüllt wird.

Wenn Sie einen Blob haben, der eine andere Zeichencodierung verwendet, können Sie die readAsText-Methode eines FileReaders verwenden. Diese Methode erlaubt die explizite Angabe einer Codierung.

stream()

Mit der stream-Methode können Sie den Inhalt eines Blobs als ReadableStream des Streams API[1] bereitstellen. Einen solchen Stream können Sie lesen oder an andere Streams weitergeben.

Weblinks

  • MDN: Streams API