How to use btoa and atob with UTF strings?
Issue: Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
This error occurs when the btoa
method has been called upon string, containing UTF-8 characters. This article tells how to resolve this issue properly.
Btoa and Atob
btoa
stays for “Binary to ASCII”, and atob
is short for “ASCII to Binary”. These methods implement the Base64 encoding in modern browsers
Base64 expects binary data as its input, but in Javascript, strings may contain more than one byte per character, as for UTF encodings.
It makes btoa
and atob
inappropriate when converting UTF strings without additional moves.
Mozilla recommends the following workaround.
toBinary() and fromBinary() workaround
In example shown at btoa
page at Mozilla Developer’s Portal, the workaround is to convert the source string into binary representation first and then pass it into btoa
.
// convert a Unicode string to a string in which
// each 16-bit unit occupies only one byte
function toBinary(string) {
const codeUnits = new Uint16Array(string.length);
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = string.charCodeAt(i);
}
return String.fromCharCode(...new Uint8Array(codeUnits.buffer));
}
Usage example:
> btoa('asd˚')
VM132:1 Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.
> btoa(toBinary('asd˚'))
"YQBzAGQA2gI="
Learn more
First, I’d recommend to visit the Mozilla’s Developer portal, especially atob() and btoa() pages, and further information on this topic present at the related Mozilla Developer Glossary page.
Written by Vladimir Ignatev