Hvorfor atob() returnerer bytes og btoa() avviser noe tekst

Forstå JavaScript binære strenger, tegnområdefeil og UTF-8 trinnet som trengs rundt atob og btoa.

Navnene atob og btoa kan foreslå vanlig tekstkonvertering. Nettleserkontrakten deres er smalere: de konverterer mellom Base64 tekst og en streng hvis tegnverdier representerer individuelle byte. Den bytestrengen er en beholder, ikke et løfte om at resultatet er lesbar Unicode-tekst.

To forskjellige strenger

JavaScript strenger bruker UTF-16 kodeenheter. En bytestreng begrenser bevisst hver tegnverdi til 0–255. btoa('Hello') fungerer fordi ASCII-verdier passer til det området. btoa('你好') mislykkes fordi disse tegnene ikke passer i én byte. Selv en karakter som passer kan være misvisende: btoa('é') koder enkeltbyte E9, ikke UTF-8 byte C3 A9 som forventes av mange tjenester.

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

Sett UTF-8 konvertering rundt bytefunksjonene

TextEncoder produserer UTF-8 byte fra tekst. Etter dekoding av Base64, en dødelig TextDecoder konverterer gyldige UTF-8 byte tilbake til tekst og avviser ugyldige sekvenser i stedet for å erstatte dem stille. Dette lille eksemplet er bevisst eksplisitt slik at grensen 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); // 中文😊

Ikke behandle et binært resultat som en brukket streng

atob('/w==') representerer byte FF. Det er ikke gyldig UTF-8 i seg selv, men det er perfekt gyldige binære data. Den riktige neste handlingen kan være en byte-nedlasting eller heksadesimal visning, ikke et annet tekstkonverteringstriks. Kjører den byte-strengen gjennom TextEncoder ville kode tegnet U+00FF og endre byte.

Nettleserdekoderen er heller ikke en komplett protokollvalidator. Akseptert mellomrom og utelatt polstring kan avvike fra strenge applikasjonskrav. Hvis en protokoll krever kanonisk koding, valider alfabet, utfylling og ubrukte biter separat. For store filer, unngå å spre en komplett byte-array inn i String.fromCharCode(...bytes); grenser for antall argumenter kan mislykkes lenge før filen blir uvanlig stor.

Les nettleserkontraktene i MDN: atob() og MDN: btoa(). Applikasjonen bør bestemme om den ønsker en tillatende konvertering, en streng validator eller en filbevarende arbeidsflyt, i stedet for å anta at det er samme oppgave.