web-dev-qa-db-fra.com

canvas.toDataURL () SecurityError

Donc, j'utilise Google Maps et j'obtiens l'image de manière à ce que cela ressemble à ceci

<img id="staticMap"
        src="http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=600x300&maptype=roadmap
&markers=color:blue%7Clabel:S%7C40.702147,-74.015794&markers=color:green%7Clabel:G%7C40.711614,-74.012318
&markers=color:red%7Ccolor:red%7Clabel:C%7C40.718217,-73.998284&sensor=false">

J'ai besoin de le sauver. J'ai trouvé ceci:

function getBase64FromImageUrl(URL) {
    var img = new Image();
    img.src = URL;
    img.onload = function() {

        var canvas = document.createElement("canvas");
        canvas.width = this.width;
        canvas.height = this.height;

        var ctx = canvas.getContext("2d");
        ctx.drawImage(this, 0, 0);

        var dataURL = canvas.toDataURL("image/png");

        alert(dataURL.replace(/^data:image\/(png|jpg);base64,/, ""));

    };
}

Mais je reçois ce problème:

Uncaught SecurityError: Impossible d'exécuter 'toDataURL' sur 'HTMLCanvasElement': les canevas altérées ne peuvent pas être exportées. 

J'ai cherché des correctifs. J'ai trouvé un exemple ici Comment utiliser CORS mais je ne parviens toujours pas à lier ces 2 codes pour le faire fonctionner. Peut-être que je le fais mal et qu'il y a un moyen plus simple de le faire? J'essaie de sauvegarder cette image pour pouvoir transférer les données sur mon serveur. Alors peut-être que quelqu'un a fait quelque chose comme ça et sait comment faire fonctionner .toDataURL() tant que j'en ai besoin?

66
user3074343

Si Google n'envoie pas cette image avec le bon en-tête Access-Control-Allow-Origin, vous ne pourrez pas utiliser son image dans la zone de dessin. Cela est dû au fait que l'approbation CORS n'a pas été approuvée. Vous pouvez en lire plus à ce sujet ici , mais cela signifie essentiellement:

Bien que vous puissiez utiliser des images sans l’approbation CORS dans votre canevas, cela souille la toile. Une fois qu'une toile a été corrompue, vous ne pouvez plus. extraire plus longtemps les données de la toile. Par exemple, vous ne pouvez pas utilisez plus longtemps le canevas toBlob (), toDataURL () ou getImageData () les méthodes; cela provoquerait une erreur de sécurité.

Cela empêche les utilisateurs d’exposer leurs données privées à l’aide d’images extraire des informations de sites Web distants sans autorisation.

Je suggère simplement de passer l'URL à votre langue côté serveur et d'utiliser curl pour télécharger l'image. Attention à bien le désinfecter!

MODIFIER:

Comme cette réponse est toujours la réponse acceptée, vous devriez vérifier la réponse de @ shadyshrif , qui consiste à utiliser:

var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;

Cela fonctionnera uniquement si vous disposez des autorisations appropriées, mais vous permet au moins de faire ce que vous voulez.

87
Prisoner

Il suffit d'utiliser l'attribut crossOrigin et de transmettre 'anonymous' en tant que deuxième paramètre.

var img = new Image();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url;
52
shady sherif

Cette méthode vous empêchera d'obtenir une erreur 'Access-Control-Allow-Origin' du serveur auquel vous accédez.

var img = new Image();
var timestamp = new Date().getTime();
img.setAttribute('crossOrigin', 'anonymous');
img.src = url + '?' + timestamp;
4
Karuban

Essayez le code ci-dessous ...

<img crossOrigin="anonymous"
     id="imgpicture" 
     fall-back="images/penang realty,Apartment,house,condominium,terrace house,semi d,detached,
                bungalow,high end luxury properties,landed properties,gated guarded house.png" 
     ng-src="https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png" 
     height="220"
     width="200"
     class="watermark">
3
ct.tan

Dans mon cas, j'utilisais le contrôle WebBrowser (en forçant IE 11) et je ne pouvais pas dépasser l'erreur. Le passage à CefSharp qui utilise Chrome a résolu le problème pour moi.

0
Brad Mathews