2011-08-20 13 views
25

PREGUNTA: ¿Qué versiones de navegador son compatibles con los encabezados CORS (Intercambio de recursos de origen) para Cross Domain Imágenes utilizados en Canvas?Navegador Canvas CORS Soporte para Cross Domain Cargado de manipulación de imágenes

CORS se puede aplicar tanto a las solicitudes XMLHttpRequests de dominio cruzado como a las solicitudes de imágenes. Esta pregunta es acerca de solicitud de imágenes Mi normal ir a la compatibilidad de la versión del navegador http://caniuse.com/cors no está claro en el tema y la búsqueda en Google no arroja buenos resultados.

Encontré un reciente blog de desarrollo de Chrome que implica que el soporte de CORS estaba muy extendido en los navegadores modernos, pero podría romperse debido a problemas de seguridad de WebGL.
http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html

Más detalles sobre CORS:

estamos considerando la viabilidad del uso de la lona & CORS con las solicitudes de imágenes de dominio cruzadas como se describe en el Proyecto de Trabajo del W3C http://www.w3.org/TR/cors/#use-cases. CORS es utilizado por lienzo html para permitir el uso de recursos de dominio cruzado de forma similar a la forma en que flash usa crossdomain.xml. Básicamente, queremos leer/editar los píxeles de datos de imagen y no queremos usar un mismo servidor proxy de origen.

Normalmente, si se cargan imágenes de dominio cruzado y se utilizan con lienzo html, el acceso a los píxeles mediante funciones como canvas.toDataURL() arrojará un error de seguridad. Sin embargo, si el servidor que entrega la imagen agrega un encabezado como este, se debe permitir el uso del dominio cruzado.

access-control-allow-origin: * 

Navegadores Nos preocupan más:

Estamos pensando en evitar la falta de apoyo de la lona de IE se utiliza el flash, por lo que para navegadores de escritorio con un problema CORS podemos hacer eso también, pero en el flash móvil no es una opción, y usar un proxy para hacer que las solicitudes sean del mismo origen no es una opción en nuestro caso de uso. Por lo tanto, estoy particularmente interesado en Andriod, Iphone, soporte de navegador de iPad para CORS.

Respuesta

19

Resultados de prueba: malas noticias, parece que solo funciona en Chrome. Todos los otros navegadores (incluyendo Android móvil) dan un error como este:

Failed: DOM Exception: SECURITY_ERR (18) 

dispositivos móviles He probado Android (Samsung Galaxy versión del kernel 2.6.32.9), Iphone y IPAD V1 y falló en las tres.

Puede probar su propio dispositivo móvil con esta URL: http://maplarge.com/CrossOriginImageTest.html

el script de prueba:

<!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

estaba a punto de publicar una pregunta acerca de esto. Me alegro de no ser el único que se vuelve loco pensando que esto * debería * funcionar. Esto ahora funciona en FF17, pero aún no funciona en IE10. Supongo que tendré que seguir usando un proxy para mis solicitudes. – pseudosavant

+2

Actualización 1.5 años después: en Windows Acabo de probar IE9 (error), Safari 5.0.5 (error), Firefox (pase) y Chrome (pase) – Glenn

+0

Comprobé la página de demostración en un iPad 3 en safari y funcionó. – metric152

3

Acabo de probar esto en mis con iOS iPhone 6, tanto en Safari y en Chrome y su página de prueba pasa la prueba. Lo habría publicado como un comentario, pero no tengo la opción de publicar un comentario en tu respuesta.

+0

¡Buenas noticias! Mi publicación tiene un año y medio, así que me complace ver que los navegadores han progresado. – Glenn

+1

He probado en Windows 8 - IE 10 y aún falla. – bfcoder

+1

probado en Mac OSX 10.7.5 - Safari 6.0.2 y pasa. – bfcoder

1

Se puede usar PHP para conseguir todo lo que quiere sin CROS, ejemplo de trabajo a continuación:

<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

Esto se parece a un servicio proxy. Si controlas el dominio que aloja la página y puedes agregar este script, debería funcionar. Sin embargo, en los casos en que no lo hace, entonces está atascado lidiando con las limitaciones de CORS. Esto es particularmente doloroso para los sitios que alojan widgets incrustables o proporcionan servicios de API, porque significa que cada usuario de la API que desea tocar imágenes con lienzo debe configurar su propio proxy de dominio específico si desea acomodar navegadores que no funcionan correctamente. implementar CORS. Debido a que el problema es común en muchos navegadores, no se puede ignorar. – Glenn

+1

Lo principal es obtener una imagen decodificada de base64 en canvas por no tener limitaciones de CORS. Y en los servicios API también es posible proporcionar a los clientes una imagen decodificada en base64 en lugar de una URL de imagen. – varoniic

+0

Si tiene menos de 32 KB, incluso puede obtener soporte para IE8. Tengo curiosidad sobre la hinchazón de conversión de texto y el rendimiento de decodificación. ¿Has ejecutado alguna estadística sobre esto? Este tipo sugiere que la hinchazón puede ser bastante grande http://appcropolis.com/javascript-encode-images-dataurl/ – Glenn

Cuestiones relacionadas