2011-11-05 151 views
30
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(); 

基本上,我在这里要做的是检索图像,并将其转换为base64。我们可以直接使用base64对文件/ blob进行编码(window.btoa()),这样就可以实现对文件/ blob的编码。 )或FileReader.readAsDataURL()。“从XHR请求获取BLOB数据

然而,blob只是[对象BLOB],而我需要从图像获取二进制,所以我可以将其转换为Base64和使用数据的img标签显示它:

任何人都知道如何实现这个?

预先感谢您!

+0

我觉得很奇怪,你获取的图像日期XHR ......它甚至工作交叉起源明智?您的域名在reddit的Access-Control-Allow-Origin列表中? – Rudie

+1

这只是一个例子,实际的域名是localhost –

回答

47

请勿在Chrome(在OSX的Chrome测试,火狐12,Safari浏览器6,iOS版Chrome浏览器,Safari浏览器的iOS)使用BlobBuilder:

EX1:http://jsfiddle.net/malraux/xGUsu/(原则)

EX2:http://jsfiddle.net/xGUsu/78/(有工作完整示例)

var xhr = new XMLHttpRequest(); 
xhr.open('GET', 'doodle.png', true); 

xhr.responseType = 'arraybuffer'; 

xhr.onload = function(e) { 
    if (this.status == 200) { 
    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(); 
+1

xhr.responseType ='blob'没有在chrome中实现,它需要是一个数组缓冲区。请参阅http://code.google.com/p/chromium/issues/detail?id=52486 –

+0

您应该指定您的问题中的所有限制,然后...... –

+1

谢谢!正是我在找的!斯科特A,你是我眼中的神。确认它有效:) –

31

您可以获取Blob并使用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">

实施例(相同的码):http://jsfiddle.net/ysangkok/sJxXk/86/。适用于Firefox和Chrome 25+。和所有其他的浏览器,除了Opera Mini的:http://caniuse.com/#search=Blob

+1

它现在在Chrome中工作(使用Chrome 25测试) –

+2

Blob构造函数可在最新的浏览器中使用。例如,如果您必须支持IE8或9,您将无法使用它。 –

+2

@JanusTroelsen如果你必须支持其中一种浏览器,那么这绝对没有什么意义(并且它比Firefox所使用的百分比还要高)。 :-)顺便说一句,IE10只有<4%,所以你基本上认为开发者应该完全忽略IE,如果你看看NetApplications而不是StatCounter,那么IE 8 + 9占桌面的44%。话虽如此,您的Blob解决方案不适用于:OS X上的Safari 6.0.2,OS X上的Firefox 12,或iPhone 4上的Safari和Chrome。 –

6

XMLHttpRequest

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(); 

在3方面创造团块图像。

  • window.URL。 createObjectURL
  • FileReadercaniuse
  • Base64String

    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; 
    }; 
    

转换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; 
}; 
+0

然后将文件保存在IE 11或Egde中:window.navigator.msSaveOrOpenBlob(blob,'filename.pdf'); – Oleksii

3

相同的溶液通过的建议加诺言...

注意!使用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%; 
 
}