2011-08-20 6 views
25

DOMANDA: Quali versioni del browser supportano intestazioni CORS (Cross-Origin Resource Sharing) per Cross Domain Immagini utilizzate in Canvas?Supporto CORS Canvas Browser per la manipolazione di immagini caricate su dominio incrociato

CORS può applicare a XMLHttpRequests su più domini e alle richieste di immagini. Questa domanda riguarda le richieste di immagini La mia normale compatibilità con browser versione http://caniuse.com/cors non è chiara sul problema e la ricerca di google non produce risultati soddisfacenti.

Ho trovato un recente blog di sviluppo di Chrome che implica che il supporto di CORS era molto diffuso nei browser moderni ma potrebbe interrompersi a causa di problemi di sicurezza WebGL.
http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html

Maggiori dettagli su CORS:

Stiamo prendendo in considerazione la possibilità di utilizzare tela & CORS con richieste di immagine dominio trasversali come descritto nel progetto di W3C Working http://www.w3.org/TR/cors/#use-cases. CORS è utilizzato da html canvas per consentire l'utilizzo di risorse cross-domain in modo simile al modo in cui flash utilizza crossdomain.xml. Fondamentalmente, vogliamo leggere/modificare i pixel dei dati dell'immagine e non vogliamo usare un server proxy di origine.

Normalmente, se le immagini sono caricate su più domini e utilizzate con canvas html, l'accesso ai pixel utilizzando funzioni come canvas.toDataURL() genera un errore di sicurezza. Tuttavia, se il server che consegna l'immagine aggiunge un'intestazione come questa, l'utilizzo del dominio incrociato dovrebbe essere consentito.

access-control-allow-origin: * 

Browser Ci tengo di più:

Stiamo progettando di aggirare la mancanza di supporto di tela di IE si usa il flash, quindi per i browser desktop con un problema CORS possiamo fare anche questo, ma su il flash mobile non è un'opzione e l'utilizzo di un proxy per rendere le richieste identiche all'origine non è un'opzione nel nostro caso d'uso. Quindi, sono particolarmente interessato ad Andriod, Iphone, supporto browser IPAD per CORS.

risposta

19

Risultati dei test: cattive notizie, sembra funzionare solo in Chrome. Tutti gli altri browser (tra cui Android mobile) danno un errore come questo:

Failed: DOM Exception: SECURITY_ERR (18) 

dispositivi mobili ho provato Android (Samsung Galaxy kernel versione 2.6.32.9), Iphone e Ipad V1 e non è riuscito in tutti e tre.

È possibile verificare il proprio dispositivo mobile con questo URL: http://maplarge.com/CrossOriginImageTest.html

lo script di test:

<!DOCTYPE html> 
<html> 
<head> 
<title>Canvas Cross Origin Image Test: Testing for Canvas Cross Domain Image CORS Support</title> 
<script type="text/javascript"> 
    function initialize() { 

     //will fail here if no canvas support 
     try { 
      var can = document.getElementById('mycanvas'); 
      var ctx = can.getContext('2d'); 
      var img = new Image(); 
      img.crossOrigin = ''; 
      //domain needs to be different from html page domain to test cross origin security 
      img.src = 'http://lobbydata.com/Content/images/bg_price2.gif'; 
     } catch (ex) { 
      document.getElementById("results").innerHTML = "<span style='color:Red;'>Failed: " + ex.Message + "</span>"; 
     } 

     //will fail here if security error 
     img.onload = function() { 
      try { 
       var start = new Date().getTime(); 
       can.width = img.width; 
       can.height = img.height; 
       ctx.drawImage(img, 0, 0, img.width, img.height); 
       var url = can.toDataURL(); // if read succeeds, canvas isn't dirty. 
       //get pixels 
       var imgd = ctx.getImageData(0, 0, img.width, img.width); 
       var pix = imgd.data; 
       var len = pix.length; 
       var argb = []; //pixels as int 
       for (var i = 0; i < len; i += 4) { 
        argb.push((pix[i + 3] << 24) + (pix[i] << 16) + (pix[i + 1] << 8) + pix[i + 2]); 
       } 
       var end = new Date().getTime(); 
       var time = end - start; 
       document.getElementById("results").innerHTML = "<span style='color:Green;'>" + 
       "Success: Your browser supports CORS for cross domain images in Canvas <br>"+ 
       "Read " + argb.length+ " pixels in "+ time+"ms</span>"; 
      } catch (ex) { 
       document.getElementById("results").innerHTML = "<span style='color:Red;'>Failed: " + ex + "</span>"; 
      } 

     } 

    } 
</script> 
</head> 
<body onload="initialize()"> 
<h2>Canvas Cross Origin Image Test: Testing for Canvas Cross Domain Image CORS Support</h2> 
<h2><a href="http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html">What is CORS Image Security?</a></h2> 
<h1 id="results" style="color:Orange;">Testing...</h1> 
<canvas id="mycanvas"></canvas> 
<br /> 
<a href="/Example/List">More Examples</a> 
</body> 
</html> 
+2

ero sul punto di inviare una domanda su questo. Sono contento di non essere l'unico a impazzire pensando che * dovrebbe * funzionare. Questo ora funziona in FF17, ma ancora non funziona in IE10. Suppongo che dovrò continuare a usare un proxy per le mie richieste. Aggiornamento – pseudosavant

+2

1.5 anni dopo: su Windows ho appena testato IE9 (fail), Safari 5.0.5 (fail), Firefox (pass) e Chrome (pass) – Glenn

+0

Controllato la pagina demo su un iPad 3 in Safari e ha funzionato. – metric152

3

Ho appena testato questo sul mio iPhone con iOS 6 sia in Safari e in Chrome e la tua pagina di test supera il test. Avrei postato questo come commento ma non mi è stata data la possibilità di pubblicare un commento per la tua risposta.

+0

Ottime notizie! Il mio post è di un anno e mezzo quindi mi fa piacere vedere che i browser hanno progredito. – Glenn

+1

Ho eseguito il test in Windows 8 - IE 10 e non riesce ancora. – bfcoder

+1

testato in Mac OSX 10.7.5 - Safari 6.0.2 e passa. – bfcoder

1

Si potrebbe utilizzare PHP per ottenere tutto ciò che si vuole, senza CROS, esempio di lavoro di seguito:

<script src="http://code.jquery.com/jquery-latest.js"></script> 
<script> 
function a(x){ 
alert(x); 
var img = new Image(); 
      img.onload = function() 
      { 
      var canvas = document.createElement("canvas"); 
      canvas.width = img.width; 
      canvas.height = img.height; 
      var context = canvas.getContext("2d"); 
      context.fillStyle = "#ffffff"; 
      context.fillRect(0,0,img.width,img.height); 
      context.drawImage(img, 0, 0); 
      var data = canvas.toDataURL('image/jpeg' , 0.8); 
      document.write('<img src="'+data+'" />'); 
      };img.src = x; 
} 
</script> 
<?php 
$im = imagecreatefromjpeg('http://www.nasa.gov/images/content/711375main_grail20121205_4x3_946-710.jpg'); 
      ob_start(); 
      imagejpeg($im,NULL,100); 
      $outputBuffer = ob_get_clean(); 
      $base64 = base64_encode($outputBuffer); 
      $x= 'data:image/jpeg;base64,'.$base64; 
      echo "<script>a('".$x."')</script>"; 
?> 
+2

Sembra un servizio proxy. Se controlli il dominio che ospita la pagina e puoi aggiungere questo script, dovrebbe funzionare. Tuttavia, nei casi in cui non lo fai, sei bloccato a gestire i limiti di CORS. Ciò è particolarmente doloroso per i siti che ospitano widget incorporabili o forniscono servizi API, perché significa che ogni utente dell'API che desidera toccare le immagini con canvas deve impostare il proprio proxy specifico del dominio se desidera ospitare i browser che non funzionano correttamente implementare CORS. Poiché il problema è comune in molti browser, non può essere ignorato. – Glenn

+1

La cosa principale è ottenere l'immagine decodificata base64 su tela perché non ci sono limiti CORS. E nei servizi API è anche possibile dare ai client l'immagine decodificata base64 anziché l'URL dell'immagine. – varoniic

+0

Se hai meno di 32KB puoi persino ottenere il supporto IE8. Sono curioso di vedere le prestazioni di conversione e decodifica del testo. Hai eseguito statistiche su questo? Questo ragazzo suggerisce che il bloat può essere abbastanza grande http://appcropolis.com/javascript-encode-images-dataurl/ – Glenn

Problemi correlati