Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Image using jQuery.ajax() and decode it to base64

Tags:

What i want to do:

HTTP-GET an image (jpeg) using jQuery.ajax() from a basic-auth secured server. it seems like i get some data of the image, it must be binary. i want to convert that to base64, because then i can insert this as an image in my html this way:

     $("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data)); 

the ajax call looks like this:

            $.ajax({                 url: "someurltoajpeg",                 type: "GET",                 headers: {                     "Authorization" : "Basic " +  btoa("user:pw")                 },                 xhrFields: {                     withCredentials: true                 }             }).done(function( data, textStatus, jqXHR ) {                 $("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data));             }).fail(function( jqXHR, textStatus, errorThrown ) {                 alert("fail: " + errorThrown);             }); 

the function base64encode looks like this:

        function base64encode(binary) {             return btoa(unescape(encodeURIComponent(binary)));         } 

i got this function from here: Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Python

there he says that it works for him. but in my case the src attribute of my image is changed, and some very long data is inserted, but only the very small symbol for that an image should be there appears. i can save that "image", thats not even there, and when i open it, my image viewer says, that it is not a jpeg file. this is not an error caused by the specific image or by the same origin policy. has anyone a solution to this? thanks

like image 666
user1963987 Avatar asked Oct 01 '13 19:10

user1963987


2 Answers

If you don't have to support IE 9, you could use FileReaderAPI to convert a blob to a data URL. It provides a readAsDataURL() method that accepts a Blob as first argument. As soon as the blob is read, it fires a load event and provides the data URL on result property.

This is way more stable and requires less code since it does not require custom encoding as base64 string, which is a complex task taking limitations of btoa into account.

You could use jQuery.ajax() or fetch to load the file as a Blob.

jQuery.ajax(url, {   dataType: 'binary',   xhr() {     let myXhr = jQuery.ajaxSettings.xhr();     myXhr.responseType = 'blob';     return myXhr;   } }).then((response) => {   // response is a Blob   return new Promise((resolve, reject) => {     let reader = new FileReader();     reader.addEventListener('load', () => {       // reader.result holds a data URL representation of response       resolve(reader.result);     }, false);     reader.addEventListener('error', () => {       reject(reader.error);     }, false);     reader.readAsDataURL(response);   }); }); 

This example code is using Promise but it would work similar if using callbacks.

like image 32
jelhan Avatar answered Sep 23 '22 18:09

jelhan


First of all, according to Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Python add the correct mimetype to the Ajax call:

 $.ajax({             url: "someurltoajpeg",             type: "GET",             headers: {                 "Authorization" : "Basic " +  btoa("user:pw")             },             xhrFields: {                 withCredentials: true             },             mimeType: "text/plain; charset=x-user-defined"         }).done(function( data, textStatus, jqXHR ) {             $("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data));         }).fail(function( jqXHR, textStatus, errorThrown ) {             alert("fail: " + errorThrown);         }); 

Then use base64Encode function described instead then the btoa:

function base64Encode(str) {         var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";         var out = "", i = 0, len = str.length, c1, c2, c3;         while (i < len) {             c1 = str.charCodeAt(i++) & 0xff;             if (i == len) {                 out += CHARS.charAt(c1 >> 2);                 out += CHARS.charAt((c1 & 0x3) << 4);                 out += "==";                 break;             }             c2 = str.charCodeAt(i++);             if (i == len) {                 out += CHARS.charAt(c1 >> 2);                 out += CHARS.charAt(((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4));                 out += CHARS.charAt((c2 & 0xF) << 2);                 out += "=";                 break;             }             c3 = str.charCodeAt(i++);             out += CHARS.charAt(c1 >> 2);             out += CHARS.charAt(((c1 & 0x3) << 4) | ((c2 & 0xF0) >> 4));             out += CHARS.charAt(((c2 & 0xF) << 2) | ((c3 & 0xC0) >> 6));             out += CHARS.charAt(c3 & 0x3F);         }         return out;     } 

bye

like image 151
gaetanoM Avatar answered Sep 24 '22 18:09

gaetanoM