我想做什么:
使用来自基本身份验证的安全服务器的jQuery.ajax()来HTTP-GET图像(jpeg)。看起来我得到了一些图像数据,它必须是二进制的。我想将其转换为base64,因为那时我可以这样在我的HTML中插入这个图像:
$("#image").attr('src', 'data:image/jpeg;base64,' + base64encode(data));
ajax调用如下所示:
$.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);
});
函数base64encode如下所示:
function base64encode(binary) {
return btoa(unescape(encodeURIComponent(binary)));
}
我从这里得到了这个功能: Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Python
在那里,他说这对他有用。但在我的情况下,我的图像的src属性被更改,并且插入了一些非常长的数据,但只有那个图像应该出现的非常小的符号。我可以保存那个“图像”,甚至不存在,当我打开它时,我的图像查看器说,它不是一个jpeg文件。这不是由特定图像或相同的原始策略引起的错误。有谁解决这个问题?感谢答案 0 :(得分:27)
首先,根据Retrieving binary file content using Javascript, base64 encode it and reverse-decode it using Python将正确的mimetype添加到Ajax调用中:
$.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);
});
然后使用base64Encode函数代替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;
}
再见
答案 1 :(得分:1)
如果不必支持Internet Explorer 9,则可以使用FileReader
API将Blob转换为数据URL。它提供了readAsDataURL()
方法,该方法接受Blob作为第一个参数。读取Blob后,它将触发load
事件,并在result
属性上提供数据URL。
这是一种更稳定的方法,所需的代码更少,因为它不需要将自定义编码作为base64字符串,这是一项复杂的任务,考虑了btoa(https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa)的局限性。
您可以使用jQuery.ajax()
或fetch
将文件作为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);
});
});
此示例代码使用的是Promise,但是如果使用回调,它的工作原理也相似。