Search code examples
javascriptbase64blobdata-urifileapi

Blob's DataUri vs Base64 string DataUri


As you know & stated in w3 it is possible to create a url for a Blob object in javascript by using Blob's createObjectUrl. On the other hand, if we have a data as a Base64 encoded string we can present it as a Url with the format "data[MIMEType];base64,[data>]".

Let's suppose that I have a base64 encoded string that was generated from an image that is very popular on these days :) "The red dot" image in wikipedia.

var reddotB64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg";

I'm 100% sure that if I create a URL conforming the Data URI Scheme as stated above, then, I'll be able to put a link element and download it from the browser: please see the code example below:

var reddotB64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg";
var reddotLink = document.createElement("a");
reddotLink.target = "_blank";
reddotLink.href = "data:image/png;base64," + reddotB64;
document.body.appendChild(reddotLink);
reddotLink.click();
document.body.removeChild(reddotLink);

This works prettywell and displays the image in a new tab. On the other hand I'll try to create the link by using Blob as follow:

var reddotB64 = "iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg";
var reddotBlob = new Blob([atob(reddotB64)], { type: 'image/png' });
var reddotLink = document.createElement("a");
reddotLink.target = "_blank";
reddotLink.href = URL.createObjectURL(reddotBlob);
document.body.appendChild(reddotLink);
reddotLink.click();
document.body.removeChild(reddotLink);

This code is decoding base64 encoded string variable reddotB64 via atob function. And then, creating a Blob object and continues with URL.createObjectURL function. In that case, since I've decoded reddotB64 from base64 to binary and created a Blob of type image/png and then create object url from that I expect it to work but it's not working.

Do you have a clue why it's not working? Or am I missing anything on the standards? Or doing something wrong in Javascript?


Solution

  • Here is the answer. Looks like it is an encoding issue. In order to convert/decode Base64 string to binary(UInt8Array/byte) using atob is not enough. After using atob it is required to use UTF-16 character code: and we achieve this by using charCodeAt function for every character in the decoded string. As a result we get UTF-16 encoded binary string which is definately working. Just create a Blob and then call URL.createObjectURL.