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.

History

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.

Usage

Simple

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

var output=btoa("Joy");

Output
Sm95

var output=btoa("Sm95");

Output
Joy

Unicode

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)
InvalidCharacterError

Base64 with unicode

The fix to this problem goes as follows for encoding


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


Output

4LSc4LWL4LSv4LWNIOC0ruC1i+C1uw==


To decode use the below


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

Output
ജോയ് മോൻ

Problem

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.

https://api.github.com/repos/joymon/joyful-visualstudio/readme

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

Sample code is in jsFiddle. Url below
http://jsfiddle.net/joygeorgek/tv3b7feL/10/

No comments: