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

2

25

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

Banquer answered 1/10, 2013 at 19:52 Comment(1)
Did you figure this out? I'm trying to do the same thing.Dedradedric
M
36

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

Mcdowell answered 18/8, 2014 at 20:3 Comment(1)
@Lori You can get more info about base64Encode in the reported link. If I may help you I'll pleased to do it, but i need you elaborate more "license". ThanksMcdowell
A
2

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.

Allanallana answered 24/9, 2018 at 20:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.