Navnene atob og btoa kan foreslå almindelig tekstkonvertering. Deres browserkontrakt er smallere: de konverterer mellem Base64 tekst og en streng, hvis tegnværdier repræsenterer individuelle bytes. Denne bytestreng er en beholder, ikke et løfte om, at resultatet er læsbar Unicode-tekst.
To forskellige strenge
JavaScript strenge bruger UTF-16 kodeenheder. En bytestreng begrænser bevidst hver tegnværdi til 0-255. btoa('Hello') virker, fordi ASCII værdier passer til det område. btoa('你好') mislykkes, fordi disse tegn ikke passer i én byte. Selv en karakter, der passer, kan være vildledende: btoa('é') koder den enkelte byte E9, ikke de UTF-8 bytes C3 A9, der forventes af mange tjenester.
console.log(btoa('é')); // 6Q== (byte E9)
console.log(btoa(String.fromCharCode(0xc3, 0xa9))); // w6k= (UTF-8)
Sæt UTF-8 konvertering omkring bytefunktionerne
TextEncoder producerer UTF-8 bytes fra tekst. Efter afkodning af Base64, en fatal TextDecoder konverterer gyldige UTF-8 bytes tilbage til tekst og afviser ugyldige sekvenser i stedet for lydløst at erstatte dem. Dette lille eksempel er bevidst eksplicit, så grænsen er synlig.
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); // 中文😊
Behandl ikke et binært resultat som en knækket streng
atob('/w==') repræsenterer byten FF. Det er ikke gyldigt UTF-8 i sig selv, men det er perfekt gyldige binære data. Den korrekte næste handling kan være en byte-download eller hexadecimal visning, ikke et andet tekstkonverteringstrick. Kører den byte-streng igennem TextEncoder ville kode tegnet U+00FF og ændre bytes.
Browser-dekoderen er heller ikke en komplet protokolvalidator. Accepteret mellemrum og udeladt polstring kan afvige fra strenge krav til anvendelse. Hvis en protokol kræver kanonisk kodning, skal du validere alfabet, udfyldning og ubrugte bits separat. For store filer skal du undgå at sprede en komplet byte-array ind i String.fromCharCode(...bytes); grænser for antal argumenter kan mislykkes længe før filen bliver usædvanlig stor.
Læs browserkontrakterne i MDN: atob() og MDN: btoa(). Applikationen bør beslutte, om den ønsker en tilladelig konvertering, en streng validator eller en filbevarende arbejdsgang, i stedet for at antage, at det er den samme opgave.