2013-03-08 16 views
31

Zajmuję się tworzeniem aplikacji, w której otrzymuję dane obrazu przechowywane w tablicy uint8Array. Następnie przekształcam te dane w obiekt typu blob, a następnie buduję adres URL obrazu.Kompatybilność przeglądarki konstruktorów Blob

kod uproszczony, aby uzyskać dane z serwera:

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

Konstruktor:

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

Blob contsructor jest przyczyną problemu. Działa dobrze we wszystkich przeglądarkach z wyjątkiem Chrome na urządzeniach mobilnych i stacjonarnych.

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

pulpitu Chrome daje mi NIEBEZPIECZNIE: ArrayBuffer values are deprecated in Blob Constructor. Use ArrayBufferView instead.

Komórka Chrome daje mi błąd : illegal constructor

Jeśli zmienię Konstruktor do pracy w Chrome nie działa w innych przeglądarkach.

+2

Zamieściłem PolyFill tutaj: http://stackoverflow.com/a/16545415/2382059 – casey

Odpowiedz

1

Got to pracę z kodem. Miałem tylko zmienić jakiś mały szczegół:

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

bb.append (dane); // dane muszą być bez nawiasów

Moja funkcja (konstruktor), który pracuje teraz dla wszystkich przeglądarek:

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

Zgaduję, że zostałeś oceniony, ponieważ nie uznałeś drugiej odpowiedzi jako ostatecznego rozwiązania. Szukanie "danych" lub "[array.buffer]", gdy twoje pytanie używało obu, nie jest dobrym powodem. – Drew

+2

kod dla "InvalidStateError" - 'new Blob ([data], {type: datatype})' wydaje się być taki sam jak oryginalny kod twojego łowczego! –

26

To są dwa różne problemy. Ostrzeżenie Chrome na komputery stacjonarne to bug w chrome, które jest poprawione od 2013-03-21.

Komórka Chrome daje typ TypeRum, ponieważ konstruktor blob nie jest obsługiwany. Zamiast tego musisz użyć starego interfejsu API BlobBuilder. Interfejs API BlobBuilder ma konstruktory BlobBuilder browser specific. Tak jest w przypadku FF6 - 12, Chrome 8-19, Mobile Chrome, IE10 i 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

Doszedłem do części śrubowej ... :) Co dalej? – Jacob

+2

'bb.append ([array.buffer])' powinno być 'bb.append (array.buffer)'. Metoda append pobiera bezpośrednio obiekt ArrayBuffer. – user113215

+0

Próbując ratować innych przed bezużytecznym polowaniem na duchy, skorzystałem z możliwości ustalenia pierwszego akapitu twojej odpowiedzi. W ciągu 13 dni od wysłania tej odpowiedzi, "Li Yin" (z raportu o błędzie, z którym się łączyłeś), poprawnie stwierdził, że: "Zarówno ArrayBuffer, jak i ArrayBufferView powinny być obsługiwane dla Parametrów Konstruktora. Musimy więc usunąć przestarzałe ostrzeżenie dla ArrayBuffer "i przesłał łatę, aby naprawić niepoprawne przestarzałe ostrzeżenie. – GitaarLAB