2013-03-08 14 views
31

Sto sviluppando un'applicazione in cui ricevo i dati di immagine memorizzati in un uint8Array. Poi trasformo questi dati in un BLOB e poi costruisco l'URL dell'immagine.Compatibilità browser costruttore Blob

codice semplificato per ottenere i dati dal server:

var array; 

var req = new XMLHttpRequest(); 
var url = "img/" + uuid + "_" +segmentNumber+".jpg"; 
req.open("GET", url, true); 
req.responseType = "arraybuffer"; 
req.onload = function(oEvent) { 
    var data = req.response;  
    array = new Int8Array(data);  
}; 

Costruttore:

out = new Blob([data], {type : datatype}); 

Il contsructor Blob sta causando problemi. Funziona bene su tutti i browser ad eccezione di Chrome su dispositivi mobili e desktop.

Uso di Blob:

// Receive Uint8Array using AJAX here 
// array = ... 
// Create BLOB 
var jpeg = new Blob([array.buffer], {type : "image/jpeg"}); 
var url = DOMURL.createObjectURL(jpeg); 
img.src = url; 

desktop Chrome mi dà un warnning: ArrayBuffer values are deprecated in Blob Constructor. Use ArrayBufferView instead.

mobile Chrome mi dà un errore: illegal constructor

Se cambio il costruttore a lavorare su Chrome fallisce su altri browser.

+2

ho postato un polyfill qui: http://stackoverflow.com/a/16545415/2382059 – casey

risposta

1

ottenuto che funziona con il vostro codice. Ho solo dovuto cambiare qualche piccolo dettaglio:

if(e.name == 'TypeError' && window.BlobBuilder){ 
     var bb = new BlobBuilder(); 
     bb.append(data); 
     out = bb.getBlob(datatype); 
     console.debug("case 2"); 
    } 

bb.append (dati); // dati devono essere senza staffe

funzione My (costruttore) che funziona ora per tutti i browser:

var NewBlob = function(data, datatype) 
{ 
    var out; 

    try { 
     out = new Blob([data], {type: datatype}); 
     console.debug("case 1"); 
    } 
    catch (e) { 
     window.BlobBuilder = window.BlobBuilder || 
       window.WebKitBlobBuilder || 
       window.MozBlobBuilder || 
       window.MSBlobBuilder; 

     if (e.name == 'TypeError' && window.BlobBuilder) { 
      var bb = new BlobBuilder(); 
      bb.append(data); 
      out = bb.getBlob(datatype); 
      console.debug("case 2"); 
     } 
     else if (e.name == "InvalidStateError") { 
      // InvalidStateError (tested on FF13 WinXP) 
      out = new Blob([data], {type: datatype}); 
      console.debug("case 3"); 
     } 
     else { 
      // We're screwed, blob constructor unsupported entirely 
      console.debug("Errore"); 
     } 
    } 
    return out; 
} 
+0

Immagino che tu sia stato marcato per non aver accreditato l'altra risposta come soluzione finale. Trif su "data" o "[array.buffer]" quando la tua domanda li utilizza entrambi non è una buona ragione. – Drew

+2

il codice per "InvalidStateError" - 'new Blob ([data], {type: datatype})' sembra lo stesso del codice originale che stai catturando! –

26

Quindi, questi sono in realtà due diversi problemi. L'avviso Chrome per desktop era un bug in chrome, che è stato risolto dal 2013-03-21.

Mobile Chrome ti dà un errore TypeE perché il costruttore blob non è supportato. Invece devi usare la vecchia API di BlobBuilder. L'API BlobBuilder ha costruttori di BlobBuilder browser specific. Questo è il caso di FF6-12, Chrome 8-19, Chrome mobile, IE10 e Android 3.0-4.2.

var array = new Int8Array([17, -45.3]); 

try{ 
    var jpeg = new Blob([array], {type : "image/jpeg"}); 
} 
catch(e){ 
    // TypeError old chrome and FF 
    window.BlobBuilder = window.BlobBuilder || 
         window.WebKitBlobBuilder || 
         window.MozBlobBuilder || 
         window.MSBlobBuilder; 
    if(e.name == 'TypeError' && window.BlobBuilder){ 
     var bb = new BlobBuilder(); 
     bb.append(array.buffer); 
     var jpeg = bb.getBlob("image/jpeg"); 
    } 
    else if(e.name == "InvalidStateError"){ 
     // InvalidStateError (tested on FF13 WinXP) 
     var jpeg = new Blob([array.buffer], {type : "image/jpeg"}); 
    } 
    else{ 
     // We're screwed, blob constructor unsupported entirely 
    } 
} 

Fiddle: http://jsfiddle.net/Jz8U3/13/

+0

Sono arrivato alla parte della vite ... :) Qual è il prossimo? – Jacob

+2

'bb.append ([array.buffer])' dovrebbe essere 'bb.append (array.buffer)'. Il metodo append prende direttamente l'oggetto ArrayBuffer. – user113215

+0

Nel tentativo di salvare gli altri da una inutile caccia ai fantasmi, mi sono permesso di fissare il primo paragrafo della risposta. Entro 13 giorni dopo aver postato questa risposta, "Li Yin" (sul bug-report a cui ti sei collegato), correttamente dichiarato: "Sia ArrayBuffer che ArrayBufferView dovrebbero essere supportati per i parametri del costruttore. Quindi dobbiamo rimuovere l'avviso deprecato per ArrayBuffer "e ha inviato una patch per correggere l'avviso deprecato errato. – GitaarLAB

Problemi correlati