2013-03-08 7 views
31

Ich entwickle eine Anwendung, wo ich Bilddaten in einem Uint8Array gespeichert bekomme. Dann transformiere ich diese Daten in einen Blob und baue dann die Bild-URL.Blob-Konstruktor-Browser-Kompatibilität

Simplified Codedaten vom Server zu erhalten:

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

Constructor:

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

The Blob contsructor Problem verursacht. Es funktioniert auf allen Browsern mit Ausnahme von Chrome auf Mobilgeräten und Desktopgeräten.

Verwendung von 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 gibt mir ein Warnning: ArrayBuffer values are deprecated in Blob Constructor. Use ArrayBufferView instead.

Mobile Chrome gibt mir ein Fehler: illegal constructor

Wenn ich ändern der Konstruktor zu arbeiten In Chrome schlägt es bei anderen Browsern fehl.

+2

Ich schrieb einen polyfill hier: http://stackoverflow.com/a/16545415/2382059 – casey

Antwort

1

Verstanden mit Ihrem Code arbeiten. Ich hatte nur ein paar kleine Detail zu ändern:

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

bb.append (Daten); // Daten ohne Klammern sein müssen

Meine Funktion (Konstruktor), die jetzt für alle Browser funktioniert:

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

Ich nehme an, Sie wurden markiert, weil Sie die andere Antwort nicht als endgültige Lösung gutzuschreiben. Wenn Sie "beide Daten" oder "[array.buffer]" verwenden, ist das kein triftiger Grund. – Drew

+2

der Code für "InvalidStateError" - 'neuer Blob ([Daten], {Typ: Datentyp})' scheint der gleiche wie der ursprüngliche Code, den Sie fangen! –

26

Also, das sind eigentlich zwei verschiedene Probleme. Die Desktop-Chrome-Warnung war eine bug in Chrome, die seit 2013-03-21 behoben ist.

Mobile Chrome gibt Ihnen einen TypeError, da der Blobkonstruktor nicht unterstützt wird. Stattdessen müssen Sie die alte BlobBuilder-API verwenden. Die BlobBuilder-API verfügt über browser specific BlobBuilder-Konstruktoren. Dies ist der Fall für FF6-12, Chrome 8-19, Mobile Chrome, IE10 und 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

Ich kam zum Schraubenteil ... :) Was kommt als nächstes? – Jacob

+2

'bb.append ([array.buffer])' sollte 'bb.append (array.buffer)' sein. Die append-Methode übernimmt das ArrayBuffer-Objekt direkt. – user113215

+0

In dem Versuch, andere vor einer nutzlosen Geisterjagd zu bewahren, habe ich mir erlaubt, den ersten Absatz Ihrer Antwort zu fixieren. Innerhalb von 13 Tagen, nachdem du diese Antwort gepostet hast, hat 'Li Yin' (auf dem Fehlerbericht, zu dem du verlinkt hast) korrekt festgestellt: "Sowohl ArrayBuffer als auch ArrayBufferView sollten für Konstruktorparameter unterstützt werden. Daher müssen wir die veraltete Warnung für ArrayBuffer entfernen "und einen Patch gesendet, um die falsche veraltete Warnung zu beheben. – GitaarLAB