1

I'm have trouble solving an issue with an AJAX request I'm making (I'm new to AJAX by the way). I have an API set-up and I'd like to retrieve a png image using an Authorization header which uses a token that I supply (which is stored in local storage). So for example, if i were to access the image with the Auth header then I would do this...

$.ajaxSetup({headers: {"Authorization" : localStorage.token}});

I'm able to retrieve the image. I can see it in the "Network" tab in Chrome, but when I append it to my div using this below...

$.ajax({
    //Use commas for several parameters
    type: 'GET',
    url: *url of image*,
    contentType: 'image/png',
    success: function (data) {
    binary = data;
    $("#image").attr("src", 'data:image/png;base64,'+ data);
}

...it comes out in this weird character format (as seen below):

div id="image" src="data:image/png;base64, PNG

IHDRww^ÀþIDATxÚìÝ|ÔWº?þ½¿ÿ½Ý.ÅâÉd2îdâ®BB ÁÝÝ )îÞbÅÝ¥TÐzi)Ô ÞRÙn»rï]»+w·{þçùÌ<Ãd]ùýV¾çõz¿H&I°Ï÷ç<çï}OÊø;æO1ªzhÔÀdÆþKȤ!......." etc

I'd like it to come back as an image or a b64 string which I can simply put into the src param. I've searched online everywhere and cannot seem to find an answer.

Any ideas? I appreciate your time greatly.

This is the response I receive

K. Janjuha
  • 167
  • 2
  • 11

2 Answers2

0

Your code is downloading the image, which is in binary format.

You need to encode the binary to base64 in order to display the image in base64. Use btoa as explained in this answer: https://stackoverflow.com/a/247261/2223027

pyb
  • 4,813
  • 2
  • 27
  • 45
  • 2
    Thanks for such a speedy response. I tried using btoa(unescape(encodeURIComponent(binary)))) where "binary" is the weird encoded string and I do in fact get what looks to be a b64 string, but when I put this in this converter here [https://codebeautify.org/base64-to-image-converter], it doesnt show the image. I don't think it's encoded the string correctly. Thanks once again - any other thoughts? – K. Janjuha Dec 23 '17 at 19:03
  • Hmm not sure why you'd have to use both `unescape` and `encodeURIComponent`. An alternative is to use [Canvas.toDataURL()](https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL) 1. Build a canvas element with the image URL 2. Get the data URL (see link above and https://stackoverflow.com/a/7101807/2223027 ) – pyb Dec 23 '17 at 20:01
  • Would I still be able to use my request headers with this? The image is coming through but I'm more convinced its just a conversion I need to carry out. I actually had a look on Chrome and the valid b64 string comes through. I opened up Inspect Element, went to the Network tab at the top, and then clicked on the image and selected preview and I can see it. I put it in the converter and it works, but I don't know how to save it. Take a look here: http://tinypic.com/r/9ia3kl/9. Many thanks once again – K. Janjuha Dec 23 '17 at 20:29
  • What happens when you do this? `binary = data; base64 = btoa(binary); $("#image").attr("src", 'data:image/png;base64,'+ base64);`. No you're right, because of the headers you'd have to use another approach to encode (convert) the binary to base64. Look at `FileReader`, the 1st solution of https://stackoverflow.com/a/20285053/2223027 – pyb Dec 23 '17 at 21:22
  • I get this error when implementing what you recommended just there: "Uncaught DOMException: Failed to execute 'btoa' on 'Window': The string to be encoded contains characters outside of the Latin1 range.". I was looking into using XMLHttpRequest but I wanted to keep things consistent and use ajax for the stuff that I'm doing. If its definitely not possible then I have no choice. Like I said, the data is here but its the difficulty of converting it. – K. Janjuha Dec 23 '17 at 22:59
  • OK I see, the `window.btoa(unescape(encodeURIComponent(str)))` trick is used to avoid the DOMException you're getting. Can you post an example of what you get when you use that? – pyb Dec 24 '17 at 01:52
  • In your success callback, you can try `var blob = new Blob([data], {type: "image/png"}); var fr = new FileReader(); fr.onload = function(e) { console.log("Read data: " + e.target.result); $("#image").attr("src", 'data:image/png;base64,'+ e.target.result); } fr.readAsDataURL(blob);` – pyb Dec 24 '17 at 01:55
  • 2
    So I tried this and got the same response that I did when I tried using btoa. The b64 string coming out is not the same that I have stored in my database so it's not converting it properly. I get a blank image. Again appreciating all the help this far: Image of what I'm getting -> http://tinypic.com/r/2im1g8h/9 – K. Janjuha Dec 24 '17 at 14:59
  • Did you share what you get with btoa? Can you try with a small GIF (a coloured bullet for instance) so the data could be pasted here? I don't see images hosted on tinyurl, I have to copy the "direct link". Can you please post elsewhere? – pyb Dec 24 '17 at 17:33
0

It seems like you are getting image file in binary data format and not the base64 format as you are expecting to put in the img tag src attribute.

If you do have image url you can put it in the img src directly no need of ajax call.

Dharmang
  • 3,018
  • 35
  • 38
  • Yeah I understand. The way I've configured everything is the way its set up. What is weird is that, I'm actually able to get the image using a Chrome extension 'ModHeader' where I can hard-code the Authorization header, but using what I've shown above, I can't seem to view it :/ – K. Janjuha Dec 23 '17 at 19:09