Tuesday, April 12, 2016

Caution JavaScript Ahead - atob() and btoa() to deal with base64 encoding

Setting the ground

JavaScript is always tricky. Because it has many garbage with it, its dynamic etc...This post aims towards how to work with base64 encoding in JavaScript.


In JavaScript if we want to work with base64 the standard methods are 
  • atob() - Used to decdode
  • btoa() - Used to encode to base64
It seems there are not much about this naming. Some people says it stands for Binary To ASCII when encoding and vice versa. Another thought is it was following C function naming. We can also think that when this was developed the aim was to write small JavaScript programs. If the programs are big it will take more time to transmit from the server to client. Language designers were concerned about that.



It's just a function which can be called normally.

var output=btoa("Joy");


var output=btoa("Sm95");



The above works well if the input is not unicode. If the input is unicode there will be an exception and the message goes as follows
In Chrome

InvalidCharacterError: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.

In IE (11)

Base64 with unicode

The fix to this problem goes as follows for encoding

var encoded = btoa(unescape(encodeURIComponent("ജോയ് മോൻ")));



To decode use the below

decoded = decodeURIComponent(escape(atob("4LSc4LWL4LSv4LWNIOC0ruC1i+C1uw==")));

ജോയ് മോൻ


The problem with this is same. It works differently in different browsers. If the encoding and decoding happens in same place, it works. But suppose if the server encodes the data and JavaScript gets it via Ajax,what will happen?

Ideally atob() should decode it and it does in Chrome and Firefox. But its not working in IE. Even in IE 11.

To be more precise the scenario is to decode the content coming from Github API. Below is a typical Github API url and it gets context in base64.


When we try to decode the base64 using atob() it will work well in Chrome and Firefox. But throw the the same error message in IE 11.

Solution - Use custom base64 library

The solution to this is to use a custom base64 library. Below is one url to such a library.

Refer this library in to the site and use below line to encode to base64

encoded = Base64.encode(inputText);

To decode

encoded = Base64.decode(encodedText);

Refer the source code of library to get more understanding of how its done.


Sample code is in jsFiddle. Url below

No comments: