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

Cookies!

We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.