我正在使用的Google API仅将图像作为二进制数据传输。
我绝对不知道如何将其放入数据URI中以显示它,感谢您的帮助!
我正在谈论的电话是this API call。
如你所见,它说:
服务器返回照片的字节。
对于调用(它是扩展名),我使用chrome_ex_oauth方法。也许我需要在标题中添加一些内容来获取真正的二进制数据,而不是现在出现的字符串......
我需要做的是将生成的二进制文件转换为数据URI,以便我可以显示它。
好的,我从XHR请求中得到了这个
现在,我不太了解二进制的东西。这是以某种方式编码的二进制数据我假设?我试图把它放到btoa和其他base64编码器中,一切都会引发错误。 我尝试使用不同的东西覆盖MySQL类型,并以某些奇怪的方式更改“响应”,但没有接受数据。
现在我有了这段代码:
var nxhr = new XMLHttpRequest();
nxhr.onreadystatechange = function (data) {
if (nxhr.readyState == 4) {
console.log(nxhr);
}
};
nxhr.open(method, url, true);
nxhr.setRequestHeader('GData-Version', '3.0');
nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
nxhr.send('Data to send');
其他任何人都知道如何为我获取这个不可理解的响应数据uri ???
感谢您的帮助
答案 0 :(得分:16)
在进行一些测试之后,这是我的答案:
要使用<img>
标记只显示图像,必须先使用Base64对结果二进制文件进行编码。您可以通过两种不同的方式完成此任务:
使用Javascript:使用Base64编码器功能such as this one。对结果二进制数据进行编码后,您可以使用<img>
标记显示图像,如下所示:<img src="data:image/*;base64,[BASE64 ENCODED BINARY]" />
。您必须将[BASE64 ENCODED BINARY]
替换为图像的实际编码二进制文件。我假设您已经知道如何通过Javascript更改HTML元素属性,将编码的二进制文件放入src
标记的<img>
属性中相当容易。
使用PHP(我的个人偏好):向API提交GET请求后,它会返回二进制文件。只需使用PHP base64_encode()
函数。
<img src="data:image/*;base64,<?php echo base64_encode($result); ?>" />
其中,$result
变量是您从API调用中获得的变量。您可以使用PHP cURL库。
我希望这会有所帮助。
答案 1 :(得分:5)
好的,我找到了解决方案......
xhr.overrideMimeType('text\/plain; charset=x-user-defined');
之后,浏览器不会触及数据。
Base64 = {
// private property
_keyStr: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
encodeBinary: function (input) {
var output = "";
var bytebuffer;
var encodedCharIndexes = new Array(4);
var inx = 0;
var paddingBytes = 0;
while (inx < input.length) {
// Fill byte buffer array
bytebuffer = new Array(3);
for (jnx = 0; jnx < bytebuffer.length; jnx++)
if (inx < input.length)
bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff; // throw away high-order byte, as documented at: https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
else
bytebuffer[jnx] = 0;
// Get each encoded character, 6 bits at a time
// index 1: first 6 bits
encodedCharIndexes[0] = bytebuffer[0] >> 2;
// index 2: second 6 bits (2 least significant bits from input byte 1 + 4 most significant bits from byte 2)
encodedCharIndexes[1] = ((bytebuffer[0] & 0x3) << 4) | (bytebuffer[1] >> 4);
// index 3: third 6 bits (4 least significant bits from input byte 2 + 2 most significant bits from byte 3)
encodedCharIndexes[2] = ((bytebuffer[1] & 0x0f) << 2) | (bytebuffer[2] >> 6);
// index 3: forth 6 bits (6 least significant bits from input byte 3)
encodedCharIndexes[3] = bytebuffer[2] & 0x3f;
// Determine whether padding happened, and adjust accordingly
paddingBytes = inx - (input.length - 1);
switch (paddingBytes) {
case 2:
// Set last 2 characters to padding char
encodedCharIndexes[3] = 64;
encodedCharIndexes[2] = 64;
break;
case 1:
// Set last character to padding char
encodedCharIndexes[3] = 64;
break;
default:
break; // No padding - proceed
}
// Now we will grab each appropriate character out of our keystring
// based on our index array and append it to the output string
for (jnx = 0; jnx < encodedCharIndexes.length; jnx++)
output += this._keyStr.charAt(encodedCharIndexes[jnx]);
}
return output;
}
};
mozilla发布的神奇内容并没有让我正确编码这些东西
bytebuffer[jnx] = input.charCodeAt(inx++) & 0xff
最终的代码看起来就像这样...
oauth.authorize(function () {
var method = "GET", params = {}, url = photo.href;
var nxhr = new XMLHttpRequest();
nxhr.onreadystatechange = function (data) {
if (nxhr.readyState == 4) {
console.log("<img src='data:image/*;base64," + Base64.encodeBinary(nxhr.response) + "' />");
}
};
nxhr.open(method, url, true);
nxhr.setRequestHeader('GData-Version', '3.0');
nxhr.setRequestHeader('Authorization', oauth.getAuthorizationHeader(url, method, params));
nxhr.overrideMimeType('text\/plain; charset=x-user-defined');
});
P.S。如果直接将“data:image / *”放入浏览器窗口,它将下载该文件,但无法打开它。但是如果你把它直接放到img src中它就可以了!
答案 2 :(得分:2)
如果您使用的是data:
URI,我认为您不关心旧浏览器。在这种情况下,请按照btoa()
中的建议使用How can you encode a string to Base64 in JavaScript?,然后再回到the alternative mentioned in the second answer。然后,data:
URI很简单:
data:image/*;base64,<the btoa output>
答案 3 :(得分:1)
所有其他解决方案都已过时。不需要Base64。查看my answer on Getting BLOB data from XHR request。
答案 4 :(得分:1)
我知道这是一个非常古老的问题,但由于这是关于 XHR 上的图像和二进制数据,所以我的秘诀在于两个重要步骤:
步骤 1: 确保您使用自定义的用户定义字符集以防止浏览器更改内容。例如
xhr.overrideMimeType('text\/plain; charset=x-user-defined');
步骤 2: 使用 String.fromCharCode(response.charCodeAt(...) & 0xff)
解决 btoa()
无法处理二进制字符串的问题。这是受到@https://gist.github.com/graylikeme/867848 要点的启发(目前对我来说是黑魔法)。
最终结果:这是结果的简化版本。请注意,通常您也会这样做,因为您还需要发送 Authorization 标头或其他内容,但这并未包含在本示例中。
<div id="output-el"></div>
<script>
var xhr = new XMLHttpRequest();
xhr.addEventListener('readystatechange', function() {
var outputEl = document.getElementById('xhr-output');
// Done?
if (this.readyState === 4) {
// Make sure this is an image.
var contentType = this.getResponseHeader('content-type');
if (contentType !== null && contentType.indexOf('image/') === 0) {
// Prepare binary response so we can base64 encode it (and btoa() function doesn't freak out).
// Thanks to: https://gist.github.com/graylikeme/867848
var response = this.responseText;
var binary = '';
for(i=0; i < response.length; i++) {
binary += String.fromCharCode(response.charCodeAt(i) & 0xff);
}
// Drop into data URI.
var encoded = btoa(binary);
outputEl.innerHTML = `<img alt="image preview" src="data:${contentType};base64,${encoded}">`;
} else {
console.log('Got a non-image response:', this.responseText);
}
}
});
// Make sure browser doesn't alter the response before we handle it.
xhr.overrideMimeType('text\/plain; charset=x-user-defined');
xhr.open('GET', 'https://example.com/path/to/some/image.jpg');
xhr.send();
</script>