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 wa
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
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.