Signatur
Beschreibung
Mit TextEncoder wandelt man einen JavaScript-String, der intern als UTF-16 vorliegt, in eine Folge von UTF-8-Bytes um. Das Ergebnis ist ein Uint8Array. Man braucht das überall dort, wo Binärdaten statt Text erwartet werden: bei der Web Crypto API (crypto.subtle.digest, sign, encrypt), bei WebSockets und WebRTC-Datenkanälen mit Binärübertragung, bei Streams, WebAssembly-Speicher, Blob-Inhalten oder wenn man die tatsächliche Bytelänge eines Strings ermitteln will.
Die Schnittstelle ist bewusst schlicht gehalten. Der Konstruktor new TextEncoder() nimmt keine Parameter entgegen, denn die Kodierung ist fest UTF-8. Die schreibgeschützte Eigenschaft encoding liefert immer "utf-8". Es gibt zwei Methoden:
encode(string)gibt ein neuesUint8Arraymit den kodierten Bytes zurück.encodeInto(string, uint8Array)schreibt die Bytes in einen bereits vorhandenen Puffer und gibt ein Objekt{ read, written }zurück. Es erzeugt dabei kein neues Array und eignet sich deshalb für leistungskritischen Code, etwa beim Schreiben in WebAssembly-Speicher.
Die Gegenrichtung, also Bytes zurück in einen String, übernimmt TextDecoder. Für kontinuierliche Datenströme gibt es TextEncoderStream, das sich in eine pipeThrough()-Kette einfügen lässt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $string | string | "" | Parameter von encode() und encodeInto(): der zu kodierende Text. Andere Werte als Strings werden mit String() umgewandelt. |
| $uint8Array Pflicht | Uint8Array | Nur bei encodeInto(): der Zielpuffer, in den die UTF-8-Bytes geschrieben werden. |
Beispiele
Instanz erzeugen und String kodieren
const encoder = new TextEncoder();
console.log(encoder.encoding);
const bytes = encoder.encode('Grüße €');
console.log(bytes);
console.log(`${'Grüße €'.length} Zeichen, ${bytes.length} Bytes`);
SHA-256-Hash eines Strings mit der Web Crypto API
const sha256 = async (text) => {
const data = new TextEncoder().encode(text);
const hashBuffer = await crypto.subtle.digest('SHA-256', data);
return [...new Uint8Array(hashBuffer)]
.map((b) => b.toString(16).padStart(2, '0'))
.join('');
};
console.log(await sha256('hallo'));
encodeInto() mit vorab reserviertem Puffer
const encoder = new TextEncoder();
const buffer = new Uint8Array(8);
const { read, written } = encoder.encodeInto('Öl & Äpfel', buffer);
console.log(read, written);
console.log(new TextDecoder().decode(buffer.subarray(0, written)));
Bytelänge prüfen, bevor gesendet wird
const MAX_BYTES = 16;
const encoder = new TextEncoder();
const passtInLimit = (text) => encoder.encode(text).byteLength <= MAX_BYTES;
console.log(passtInLimit('Hallo Welt'));
console.log(passtInLimit('😀😀😀😀😀'));
// Wichtig · Fallstricke
- Nur UTF-8: Anders als in alten Entwürfen der Spezifikation akzeptiert der Konstruktor kein Kodierungs-Argument mehr, ein übergebenes Argument wird einfach ignoriert. Für ISO-8859-1, UTF-16 und ähnliche Kodierungen braucht man eine eigene Umsetzung oder eine Bibliothek.
TextDecoderkann dagegen viele Kodierungen lesen. - Zeichenzahl und Bytezahl unterscheiden sich:
string.lengthzählt UTF-16-Codeeinheiten, nicht Bytes. Umlaute belegen in UTF-8 2 Bytes, das €-Zeichen 3 und Emojis 4. Wenn Speicher- oder Protokollgrenzen einzuhalten sind, sollte man immerencode(text).byteLengthmessen. - Einzelne Surrogate: Ungültige, einzeln stehende UTF-16-Surrogate werden stillschweigend durch U+FFFD (
EF BF BD) ersetzt. Ein Hin- und Rückweg über Kodieren und Dekodieren gibt solche Strings deshalb nicht verlustfrei wieder. - Puffergröße bei
encodeInto(): Ist der Puffer zu klein, wird still abgeschnitten, und zwar nur an Zeichengrenzen. Anhand vonreadundwrittenmuss man selbst prüfen, ob alles hineingepasst hat. Ein Puffer mittext.length * 3Bytes reicht garantiert aus. - Wiederverwenden: Eine Instanz hat keinen Zustand und kann beliebig oft benutzt werden. In Schleifen sollte man sie also nicht jedes Mal neu anlegen.
- Kompatibilität: Alle modernen Browser unterstützen die Schnittstelle, auch in Web Workern. In Node.js ist sie ab Version 11 global verfügbar, davor über
require('util').TextEncoder.encodeInto()kam später hinzu (Chrome 74, Firefox 66, Safari 14.1). Internet Explorer unterstützt die Schnittstelle nicht.