In order to protect pixel data of images, videos, and canvases on your website, the HTML5 canvas specification has safeguards in place to prevent scripts from other domains from accessing these media, manipulating them, and then creating new images, videos, or canvases.
Before anything is drawn on the canvas, the canvas tag has an origin-clean flag that's set to true. This basically means that the canvas is "clean". If you draw an image onto the canvas that's hosted on the same domain as the code running it, the origin-clean flag remains true. If, however, you draw an image onto the canvas that's hosted on another domain, the origin-clean flag is set to false and the canvas is now "dirty".
According to the HTML5 canvas specification, the canvas is considered dirty the moment any of these actions occur:
The element's 2D context's
drawImage()
method is called with anHTMLImageElement
or anHTMLVideoElement
whose origin is not the same as that of the Document object that owns the canvas element.The element's 2D context's
drawImage()
method is called with anHTMLCanvasElement
whose origin-clean flag is false.The element's 2D context's
fillStyle
attribute is set to aCanvasPattern
object that was created from anHTMLImageElement
or anHTMLVideoElement
whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created.The element's 2D context's
fillStyle
attribute is set to aCanvasPattern
object that was created from anHTMLCanvasElement
whose origin-clean flag was false when the pattern was created.The element's 2D context's
strokeStyle
attribute is set to aCanvasPattern
object that was created from anHTMLImageElement
or anHTMLVideoElement
whose origin was not the same as that of the Document object that owns the canvas element when the pattern was created.The element's 2D context's
strokeStyle
attribute is set to aCanvasPattern
object that was created from anHTMLCanvasElement
whose origin-clean flag was false when the pattern was created.The element's 2D context's
fillText()
orstrokeText()
methods are invoked and consider using a font that has an origin that is not the same as that of the Document object that owns the canvas element. (The font doesn't even have to be used; all that matters is whether the font was considered for any of the glyphs drawn.)
In addition, if you perform any of these actions on your local computer (not a web server), the origin-clean flag will automatically be set to false because the resources will be perceived to have come from a different origin.
Next, according to the specification, a SECURITY_ERR
exception will be thrown if any of these actions occur with a dirty canvas:
Although the canvas security specification was created with good intentions, it may cause us more of a headache than it's worth. As an example, let's say that you wanted to create a drawing application that hooks into the Flickr API to pull in images from the public domain to add to your drawings. If you wanted your application to be able to save that drawing as an image using the toDataURL()
method
, or if you wanted your application to have fancy pixel manipulation algorithms using the getImageData()
method
, you're in some trouble. Performing these actions on a dirty canvas will throw a JavaScript error and prevent your application from working correctly.
One way to circumvent this problem is by creating a proxy that obtains images from another domain and then passes it back to the client, making it look as if the image came from your domain. If you've ever worked with cross-domain AJAX applications, you'll feel right at home.