Получение данных BLOB из запроса XHR

    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.

читать в комментариях здесь, в нем говорится: "Конечно. После извлечения ресурса в качестве ArrayBuffer создайте из него blob. Как только у вас это будет, вы можете base64 кодировать файл/blob напрямую (окно.btoa ()) или FileReader.readAsDataURL()."

однако, blob это просто [object blob], в то время как мне нужно получить двоичный файл из изображения, чтобы я мог конвертировать это base64 и отображать его в теге img, используя данные:

кто-нибудь знает, как этого добиться?

спасибо заранее!

4 ответов


Не используйте BlobBuilder в Chrome (протестировано в OSX Chrome, Firefox 12, Safari 6, iOS Chrome, iOS Safari):

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

вы можете принести 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


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

создание blob-изображения в 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%;
    }