Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to fix getImageData() error The canvas has been tainted by cross-origin data?

My code is working very well on my localhost but it is not working on the site.

I got this error from the console, for this line .getImageData(x,y,1,1).data:

Uncaught SecurityError: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. 

part of my code:

jQuery.Event.prototype.rgb=function(){
        var x =  this.offsetX || (this.pageX - $(this.target).offset().left),y =  this.offsetY || (this.pageY - $(this.target).offset().top);
        if (this.target.nodeName!=="CANVAS")return null;
        return this.target.getContext('2d').getImageData(x,y,1,1).data;
    }

Note: my image url (src) is from a subdomain url

like image 914
Erfan Safarpoor Avatar asked Oct 07 '22 15:10

Erfan Safarpoor


People also ask

How do you fix tainted canvas?

Once a canvas has been tainted, you can no longer pull data back out of the canvas. By loading the canvas from cross origin domain, you are tainting the canvas. You can prevent this by setting crossorigin="anonymous" .

What is tainted canvas?

Security and tainted canvases A tainted canvas is one which is no longer considered secure, and any attempts to retrieve image data back from the canvas will cause an exception to be thrown.


2 Answers

As others have said you are "tainting" the canvas by loading from a cross origins domain.

https://developer.mozilla.org/en-US/docs/HTML/CORS_Enabled_Image

However, you may be able to prevent this by simply setting:

img.crossOrigin = "Anonymous";

This only works if the remote server sets the following header appropriately:

Access-Control-Allow-Origin "*"

The Dropbox file chooser when using the "direct link" option is a great example of this. I use it on oddprints.com to hoover up images from the remote dropbox image url, into my canvas, and then submit the image data back into my server. All in javascript

like image 152
matt burns Avatar answered Oct 09 '22 04:10

matt burns


I found that I had to use .setAttribute('crossOrigin', '') and had to append a timestamp to the URL's query string to avoid a 304 response lacking the Access-Control-Allow-Origin header.

This gives me

var url = 'http://lorempixel.com/g/400/200/';
var imgObj = new Image();
imgObj.src = url + '?' + new Date().getTime();
imgObj.setAttribute('crossOrigin', '');
like image 54
Kirby Avatar answered Oct 09 '22 04:10

Kirby