Javascript 从 XHR 请求中获取 BLOB 数据
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/8022425/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting BLOB data from XHR request
提问by Nick Bennet
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://static.reddit.com/reddit.com.header.png', true);
xhr.responseType = 'arraybuffer';
xhr.onload = function(e) {
if (this.status == 200) {
var uInt8Array = new Uint8Array(this.response);
var byte3 = uInt8Array[4];
var bb = new WebKitBlobBuilder();
bb.append(xhr.response);
var blob = bb.getBlob('image/png');
var base64 = window.btoa(blob);
alert(base64);
}
};
xhr.send();
Basically, what I am trying to do here is retrieve an image, and convert it to base64.
基本上,我在这里尝试做的是检索图像,并将其转换为 base64。
From reading in the comments here, it states:
从阅读这里的评论来看,它指出:
"Sure. After fetching a resource as an ArrayBuffer, create a blob from it. Once you have that, you could base64 encode the file/blob directly
window.btoa()
orFileReader.readAsDataURL()
."
“当然。在将资源作为 ArrayBuffer 获取后,从中创建一个 blob。一旦有了它,您就可以直接对文件/blob 进行 base64 编码
window.btoa()
或FileReader.readAsDataURL()
.”
However, blob
is just [object blob]
, while I need to get the binary from the image so I can convert it to base64 and display it in a img tag using data.
但是,blob
只是[object blob]
,而我需要从图像中获取二进制文件,以便我可以将其转换为 base64 并使用 data.img 标签将其显示在 img 标签中。
Anyone know how to achieve this?
有谁知道如何实现这一目标?
Thank you in advance!
先感谢您!
回答by Scott A
Don't use BlobBuilder in Chrome (tested in OSX Chrome, Firefox 12, Safari 6, iOS Chrome, iOS Safari):
不要在 Chrome 中使用 BlobBuilder(在 OSX Chrome、Firefox 12、Safari 6、iOS Chrome、iOS Safari 中测试):
ex1 : http://jsfiddle.net/malraux/xGUsu/(principle)
ex1:http: //jsfiddle.net/malraux/xGUsu/(原理)
ex2: http://jsfiddle.net/xGUsu/78/(working with full example)
ex2:http: //jsfiddle.net/xGUsu/78/(使用完整示例)
var xhr = new XMLHttpRequest();
xhr.open('GET', 'doodle.png', true);
xhr.responseType = 'arraybuffer';
// Process the response when the request is ready.
xhr.onload = function(e) {
if (this.status == 200) {
// Create a binary string from the returned data, then encode it as a data URL.
var uInt8Array = new Uint8Array(this.response);
var i = uInt8Array.length;
var binaryString = new Array(i);
while (i--)
{
binaryString[i] = String.fromCharCode(uInt8Array[i]);
}
var data = binaryString.join('');
var base64 = window.btoa(data);
document.getElementById("myImage").src="data:image/png;base64," + base64;
}
};
xhr.send();
Note: This code is over 7 years old at this point.While it should still function in most browsers, here's an updated version based on a suggestion by @TypeError that will only work in more modern browsers with the possible exception of iOS Safari(which may or may not support responseType = 'blob'
- make sure to test!):
注意:此时此代码已超过 7 年。虽然它应该仍然可以在大多数浏览器中运行,但这里有一个基于@TypeError 建议的更新版本,它只能在更现代的浏览器中运行,iOS Safari 可能除外(可能支持也可能不支持responseType = 'blob'
- 请务必测试!):
var xhr = new XMLHttpRequest();
xhr.open('get', 'doodle.png', true);
// Load the data directly as a Blob.
xhr.responseType = 'blob';
xhr.onload = () => {
document.querySelector('#myimage').src = URL.createObjectURL(this.response);
};
xhr.send();
回答by Janus Troelsen
You can fetch a Blob
and use window.URL.createObjectURL
. This prevents building giant strings and copying everything a couple of times.
您可以获取 aBlob
并使用window.URL.createObjectURL
. 这可以防止构建巨大的字符串并多次复制所有内容。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://i.imgur.com/sBJOoTm.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
if (this.status == 200) {
var blob = this.response;
document.getElementById("myImage").src = window.URL.createObjectURL(blob);
}
};
xhr.onerror = function(e) {
alert("Error " + e.target.status + " occurred while receiving the document.");
};
xhr.send();
<img id="myImage">
Example (same code): http://jsfiddle.net/ysangkok/sJxXk/86/. Works in Firefox and Chrome 25+. And all other browsers except Opera Mini: http://caniuse.com/#search=Blob
示例(相同代码):http: //jsfiddle.net/ysangkok/sJxXk/86/。适用于 Firefox 和 Chrome 25+。以及除 Opera Mini 之外的所有其他浏览器:http: //caniuse.com/#search=Blob
回答by Yash
var xmlhttp = new XMLHttpRequest();
xmlhttp.open('GET', 'http://RestServiceURL-Returns Image', true);
xmlhttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
xmlhttp.responseType = 'arraybuffer/blob';
xmlhttp.send();
creating blob image in 3-ways.
以 3 种方式创建 blob 图像。
- window.URL.createObjectURL
- FileReader(caniuse)
xmlhttp.onload = function() { var blob = new Blob([this.response], {type: 'image/png'}); console.log(blob, blob.type, this.response, typeof this.response); var image = document.getElementById('my-image'); 1)image.src = window.URL.createObjectURL(blob); 2)var fileReader = new window.FileReader(); fileReader.readAsDataURL(blob); fileReader.onloadend = function() { image.src = fileReader.result; } 3)var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(this.response))); image.src = 'data:image/png;base64,'+base64String; };
- 窗口.URL。创建对象URL
- FileReader( caniuse)
xmlhttp.onload = function() { var blob = new Blob([this.response], {type: 'image/png'}); console.log(blob, blob.type, this.response, typeof this.response); var image = document.getElementById('my-image'); 1)image.src = window.URL.createObjectURL(blob); 2)var fileReader = new window.FileReader(); fileReader.readAsDataURL(blob); fileReader.onloadend = function() { image.src = fileReader.result; } 3)var base64String = btoa(String.fromCharCode.apply(null, new Uint8Array(this.response))); image.src = 'data:image/png;base64,'+base64String; };
Converting ArrayBuffer to Blobto ArrayBuffer
将 ArrayBuffer 转换为Blob到 ArrayBuffer
1)var dataView = new DataView(arrayBuffer);
var blob = new Blob([dataView], { type: mimeString });
2)fileReader.readAsArrayBuffer(blob);
var arrayBuffer;
fileReader.onload = function() {
arrayBuffer = this.result;
};
回答by Jakob E
Same solution as suggested by Janus Troelsenwith promise added...
与Janus Troelsen建议的解决方案相同,并添加了承诺......
Note!when using createObjectURL- don't forget to call revokeObjectURL
笔记!使用createObjectURL 时- 不要忘记调用revokeObjectURL
// Load blob (promise)
function loadBlob( url ){
return new Promise( (resolve, reject) => {
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(xhr.statusText);
xhr.send();
});
}
// Create image from blob (createObjectURL)
function imageFromBlob( blob ){
const img = new Image();
img.onload = () => URL.revokeObjectURL(img.src);
img.src = URL.createObjectURL(blob);
return img;
}
// Create image from blob if loaded successfully
loadBlob('https://unsplash.it/960/540?random')
.then( blob => {
document.body.appendChild( imageFromBlob(blob) );
})
.catch( error => {
console.log('Could not load image');
})
// Alternate version adding promise to xhr
// if you like to trigger xhr.send() yourself
function xhrBlob(url){
const xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'blob';
xhr.promise = new Promise((resolve, reject) => {
xhr.onload = () => resolve(xhr.response);
xhr.onerror = () => reject(xhr.statusText);
});
xhr.load = ( onsuccess = () => {}, onerror = () => {} ) => {
xhr.promise.then(onsuccess).catch(onerror);
xhr.send();
return xhr;
}
return xhr;
}
// Using load callbacks
xhrBlob('https://unsplash.it/960/540?random')
.load(
// on sussess
blob => {
document.body.appendChild( imageFromBlob(blob) );
},
// on error
error => {
console.log('Could not load image');
}
);
// Using promise (delayed)
const image = xhrBlob('https://unsplash.it/960/540?random');
// Promise handlers
image.promise
.then( blob => {
document.body.appendChild( imageFromBlob(blob) );
})
.catch( error => {
console.log('Could not load image');
});
// Load image (will trigger promise handlers)
setTimeout(image.load, 3000);
img {
width: 100%;
}