2011-11-05 16 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(); 

Fondamentalmente, quello che sto cercando di fare qui è recuperare un'immagine e convertirla in base64.Ottenere dati BLOB dalla richiesta XHR

Dalla lettura nei commenti here, si afferma "Certo. Dopo aver recuperato una risorsa come ArrayBuffer, creare un blob da esso. Una volta che hai, potresti codificare in base64 il file/blob direttamente (window.btoa()) o FileReader.readAsDataURL(). "

Tuttavia, blob è solo [blob oggetto], mentre ho bisogno di ottenere il binario da l'immagine in modo che posso convertirlo in base64 e visualizzarli in un tag img utilizzando i dati:

Qualcuno sa come raggiungerlo Questo?

Grazie in anticipo!

+0

Trovo molto strano che si recupera la data di immagine con XHR ... lo fa anche il lavoro origine croce saggio? Il tuo dominio è nell'elenco di Access-Control-Allow-Origin di reddit? – Rudie

+1

Questo è solo un esempio, il dominio attuale è localhost –

risposta

47

Non utilizzare BlobBuilder in Chrome (testato in OSX Chrome, Firefox 12, Safari 6, iOS Chrome, Safari iOS):

EX1: http://jsfiddle.net/malraux/xGUsu/ (principio)

EX2: http://jsfiddle.net/xGUsu/78/ (lavorando con completo esempio)

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' non è implementato in chrome, deve essere un arraybuffer. Vedi http://code.google.com/p/chromium/issues/detail?id=52486 –

+0

Devi specificare tutte le restrizioni nella tua domanda quindi ... –

+1

GRAZIE! Proprio quello che stavo cercando! Scott A, sei un dio nei miei occhi. Confermato funziona :) –

31

è possibile recuperare un Blob e utilizzare window.URL.createObjectURL. Ciò impedisce di costruire stringhe giganti e di copiare tutto un paio di volte.

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">

Esempio (stesso codice): http://jsfiddle.net/ysangkok/sJxXk/86/. Funziona con Firefox e Chrome 25+. E tutti gli altri browser ad eccezione di Opera Mini: http://caniuse.com/#search=Blob

+1

Funziona in Chrome ora (testato con Chrome 25) –

+2

Il costruttore Blob è solo disponibile nei nuovi browser. Ad esempio, se devi supportare IE8 o 9 non sarai in grado di usarlo. –

+2

@JanusTroelsen Che significa assolutamente nulla se devi supportare uno di quei browser (ed è una percentuale maggiore di quella usata da Firefox a prescindere). :-) Incidentalmente, IE10 è solo <4%, quindi stai essenzialmente sostenendo che gli sviluppatori dovrebbero ignorare completamente IE, e se guardi NetApplications invece di StatCounter allora IE 8 + 9 è il 44% del desktop. Detto questo, la soluzione Blob non funziona su: Safari 6.0.2 su OS X, Firefox 12 su OS X o Safari e Chrome sul mio iPhone 4s. –

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

immagine blob creando in 3 vie.

  • window.URL. createObjectURL
  • FileReader (caniuse)
  • 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; 
    }; 
    

Conversione ArrayBuffer a Blob a 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

quindi per salvare il file in IE 11 o Egde: window.navigator.msSaveOrOpenBlob (blob, 'filename.pdf'); – Oleksii

3

Stessa soluzione come suggerito da Janus Troelsen con promessa aggiunta ...

Nota! quando si utilizza createObjectURL - non dimenticate di chiamare 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%; 
 
}

Problemi correlati