Browser Canvas cors prise en charge de la Manipulation D'images chargées dans plusieurs domaines
QUESTION: Quelles versions de navigateur prennent en charge les en-têtes CORS (Cross-Origin Resource Sharing) pour les images Cross Domain utilisées dans Canvas?
CORS peut s'appliquer à la fois aux xmlhttprequests inter-domaines et aux demandes d'image. Cette question concerne demandes d'image Mon aller normal pour la compatibilité de la version du navigateur http://caniuse.com/cors n'est pas clair sur la question et la recherche google ne donne pas de bons résultats.
J'ai trouvé un récent blog de développement chrome ce qui implique que le support CORS était largement répandu dans les navigateurs modernes mais pourrait casser en raison de la sécurité WebGL problems.
http://blog.chromium.org/2011/07/using-cross-domain-images-in-webgl-and.html
Plus de détails sur la SCRO:
Nous considérons la viabilité de l'utilisation de canvas & CORS avec des demandes d'images inter-domaines comme décrit dans le projet de travail du W3C http://www.w3.org/TR/cors/#use-cases . CORS est utilisé par html canvas pour autoriser les ressources inter-domaines utilisation d'une manière similaire à la façon dont flash utilise crossdomain.XML. Fondamentalement, nous voulons lire / éditer les pixels de données d'image et nous ne voulons pas utiliser un même serveur proxy d'origine.
Normalement, si les images sont chargées cross domain et utilisées avec html canvas, accéder aux pixels en utilisant des fonctions comme canvas.toDataURL() va lancer une erreur de sécurité. Cependant, si le serveur fournissant l'image ajoute un en-tête comme celui-ci, l'utilisation croisée des domaines devrait être autorisée.
access-control-allow-origin: *
Navigateurs Nous Nous Soucions Le Plus Sur:
Nous prévoyons de contourner le manque de support canvas D'IE en utilisant flash, donc pour les navigateurs de bureau avec un problème CORS, nous pouvons le faire aussi, mais sur mobile flash n'est pas une option, et utiliser un proxy pour faire les demandes même origine n'est pas une option dans notre cas d'utilisation. Donc, je suis particulièrement intéressé par Andriod, Iphone, support du navigateur IPAD pour CORS.
3 réponses
Résultats des tests : mauvaises nouvelles, il semble ne fonctionner que dans Chrome. Tous les autres navigateurs (y compris les mobiles Android) donnent une erreur comme ceci:
Failed: DOM Exception: SECURITY_ERR (18)
Appareils mobiles j'ai testé Android (Samsung Galaxy kernel version 2.6.32.9), Iphone et IPAD V1 et il a échoué dans les trois.
Vous pouvez tester votre propre appareil mobile avec cette URL: http://maplarge.com/CrossOriginImageTest.html
Le Script De 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>
Je viens de tester cela sur mon iPhone exécutant iOS 6 dans Safari et dans Chrome et votre page de test passe le test. J'aurais posté un commentaire mais je ne suis pas la possibilité de poster un commentaire à votre réponse.
Vous pouvez utiliser php pour obtenir tout ce que vous voulez sans CROS, exemple de travail ci-dessous:
<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>";
?>