Warum atob() Bytes zurückgibt und btoa() Text ablehnt

Verstehen Sie JavaScript-Binärzeichenfolgen, Zeichenbereichsfehler und den UTF-8-Schritt, der für atob und btoa erforderlich ist.

Die Namen atob und btoa kann eine gewöhnliche Textkonvertierung vorschlagen. Ihr Browservertrag ist enger: Sie konvertieren zwischen Base64 Text und einer Zeichenfolge, deren Zeichenwerte einzelne Bytes darstellen. Diese Bytefolge ist ein Container und kein Versprechen, dass das Ergebnis lesbarer Unicode-Text ist.

Zwei verschiedene Saiten

JavaScript-Strings verwenden UTF-16-Codeeinheiten. Eine Bytefolge beschränkt jeden Zeichenwert bewusst auf 0–255. btoa('Hello') funktioniert, weil die Werte von ASCII in diesen Bereich passen. btoa('你好') schlägt fehl, weil diese Zeichen nicht in ein Byte passen. Auch ein passender Charakter kann irreführend sein: btoa('é') kodiert das einzelne Byte E9, nicht die UTF-8 Bytes C3 A9, die von vielen Diensten erwartet werden.

console.log(btoa('é')); // 6Q== (byte E9)
console.log(btoa(String.fromCharCode(0xc3, 0xa9))); // w6k= (UTF-8)

Setzen Sie die Konvertierung UTF-8 um die Byte-Funktionen

TextEncoder Erzeugt UTF-8 Bytes aus Text. Nach der Dekodierung von Base64 ein fataler Fehler TextDecoder Konvertiert gültige UTF-8-Bytes zurück in Text und weist ungültige Sequenzen zurück, anstatt sie stillschweigend zu ersetzen. Dieses kleine Beispiel ist bewusst explizit, damit die Grenze sichtbar ist.

const text = '中文😊';
const bytes = new TextEncoder().encode(text);
let binary = '';
for (const byte of bytes) binary += String.fromCharCode(byte);
const encoded = btoa(binary);
console.log(encoded); // 5Lit5paH8J+Yig==
const decodedBytes = Uint8Array.from(atob(encoded), c => c.charCodeAt(0));
const decoded = new TextDecoder('utf-8', { fatal: true }).decode(decodedBytes);
console.log(decoded); // 中文😊

Behandeln Sie ein binäres Ergebnis nicht als defekte Zeichenfolge

atob('/w==') stellt das Byte FF dar. Es ist für sich genommen kein gültiger UTF-8, aber es handelt sich um vollkommen gültige Binärdaten. Die richtige nächste Aktion könnte ein Byte-Download oder eine Hexadezimalansicht sein, kein anderer Trick zur Textkonvertierung. Durchlaufen dieser Bytefolge TextEncoder würde das Zeichen U+00FF kodieren und die Bytes ändern.

Der Browser-Decoder ist auch kein vollständiger Protokollvalidator. Akzeptierte Leerzeichen und weggelassene Auffüllungen können von den strengen Anwendungsanforderungen abweichen. Wenn ein Protokoll eine kanonische Codierung erfordert, validieren Sie Alphabet, Auffüllung und nicht verwendete Bits separat. Vermeiden Sie bei großen Dateien die Verteilung eines vollständigen Byte-Arrays String.fromCharCode(...bytes); Grenzwerte für die Argumentanzahl können fehlschlagen, lange bevor die Datei ungewöhnlich groß wird.

Lesen Sie die Browserverträge ein MDN: atob() und MDN: btoa(). Die Anwendung sollte entscheiden, ob sie eine freizügige Konvertierung, einen strikten Validator oder einen dateierhaltenden Workflow wünscht, anstatt davon auszugehen, dass es sich hierbei um dieselbe Aufgabe handelt.