Title: How to check, if a canvas element has been tainted?
Tags: javascript;html5-canvas;cors
Question: Basic scenario

I'm loading several images on the client side. Some of them are from another domain, some are not. Some I may be able to access using the ```crossOrigin``` attribute, some not.

The basic requirement is to retrieve a dataURL for the images where possible.

Question

After drawing the image to the canvas element (which I need to to to get a dataURL, right?), how can I check, without a ```try ... catch``` block, whether the canvas has been tainted? If the canvas is tainted, I can't use ```toDataURL()``` anymore (see MDN).

```var image = new Image(),
    canvas = document.createElement( 'canvas' ),
    context = canvas.getContext( '2d' );

image.onload = function(){

  // adjust dimensions of canvas
  canvas.width = image.width;
  canvas.height = image.height;

  // insert image
  context.drawImage( image, 0, 0 );

  // how to check here?

  // get dataurl
  dataurl = tmpCanvas.toDataURL();

  // do stuff with the dataurl
};
image.src = src;  // some cross origin image
```

Comment: @monsur that is internal for the browser (the specs are for browser implementers).

Comment: This is a great question. I don't know of any way other than try/catch. But if you have a reference to the `image` variable, you could call `image.crossOrigin`. Expanding on this idea, you could create a global object that maps images to their corresponding crossOrigin variable. Checking if the image is tainted would then be a matter of iterating over the object and see what the crossOrigin values are.

Comment: Also, it looks like canvas contexts have an internal `origin-clean` variable: 

http://www.w3.org/TR/html5/scripting-1.html#concept-canvas-origin-clean

but as far as i can tell, this isn't exposed to the user.

Comment: @Cryptoburner Yup, that is true. But the discussion below indicates a good need for this property. It is something that should be brought up in the HTML5 spec.


Here is another answer: Here is a solution that doesn't add properties to native objects:

```function isTainted(ctx) {
    try {
        var pixel = ctx.getImageData(0, 0, 1, 1);
        return false;
    } catch(err) {
        return (err.code === 18);
    }
}
```

Now simply check by doing this:

```if (isTainted(ctx)) alert('Sorry, canvas is tainted!');
```

Edit: NOW i see you wanted a solution without try-catch. Though, this is the proper way to check as there is no origin clean flag exposed to user (it's for internal use only). Adding properties to native object is not recommended.

Comment for this answer: @markE yes, it's dynamically (one reason why we love it!) but with our own objects ;) It does most likely no harm whatsoever in this case but in general it's considered bad practice if it can be solved other ways (which it can in this case).
Comment for this answer: @markE I don't mind changing objects if needed. My point is if "*you know what you're doing*" there's no problem. However, there will be beginners reading the posts and I think it's wise not to give the impression that it's a fully OK practice as experience has shown that it isn't (if you *don't* know what you're doing). It's better to be on the safe-side in places like SO IMO & when users are experienced enough they'll figure out what is and isn't good to do. But I didn't intend to start any discussion - it was meant as an advice which I think is a good advice. jQuery is btw a special case.
Comment for this answer: Yep, since CORS errors are fatal this quick if-else test fails also  :-(.  I agree  there should be an  exposed flag to indicate a tainted canvas.  Even thought the question explicitly asks not, I would probably use try-catch here also.  After all the questioner is not trying to smooth over errors created by poor coding. He’s just trying to determine the state of the canvas.
Comment for this answer: **Jumping on my soapbox** ;-)  I would better say "modifying the functionality of existing properties of a native object is not recommended."   IMHO, the nature of javascript is an open prototypical language that encourages you create and extend objects.  That’s my 2-cents ;)
Comment for this answer: **Again on soapbox :-)**  Adding (not replacing) properties / methods on native objects is common.  Even John Resig (creator of jQuery!) extends native objects (example: http://ejohn.org/blog/fast-javascript-maxmin/)  Certainly, if adding properties is not to your liking, you can encapsulate the native object into your own object and extend your own object.  Or just create an array that holds which images are tainted.  Lots of workarounds to suite every programmers style!  Anyway, SO's auto-moderator will get mad at us for this discussion--but it's been fun discussing with you!  :-)
Comment for this answer: We just have different philosophies about adding properties to make native objects useful.  I respect your philosophy :)
Comment for this answer: Adding properties to native objects is widely considered bad practice because it blacklists property names that future versions of JavaScript can use without breaking (widespread) libraries. Just search `smooshMap` for an example.

Here is another answer: Here's an indirect test for CORS tainting that doesn't use try-catch:

A Demo:  http://jsfiddle.net/m1erickson/uDt2K/

It works by setting a ```image.tainted=true``` flag before loading the image

Then in image.onload, ```context.getImageData``` triggers/doesn't trigger a CORS violation.  

If no violation occurs, then the tainted flag is set to false (```image.tainted=false```).

```var img=new Image();

// set a "tainted flag to the image to true (initialize as tainted)
img.tainted=true;

img.onload=function(){

    // try an action that triggers CORS security

    var i=ctx.getImageData(1,1,1,1);

    // if we don't get here, we violated CORS and "tainted" remains true

    // if we get here, CORS is happy so set the "tainted" flag to false

    img.tainted=false;

};

// test with tainted image

img.src="http://pp-group.co.uk/wp/wp-content/uploads/2013/10/house-illustration-web.gif";
```

Since image.onload is asynchronous, your code outside image.onload will still execute even after a CORS violation.

Here's example code that:


creates an image object
tests if the image is CORS compliant
executes one callback if the image is compliant
executes another callback if the image is not compliant


Example Code:

```<!doctype html&gt;
<html&gt;
<head&gt;
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /&gt; <!-- reset css --&gt;
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"&gt;</script&gt;
<style&gt;
    body{ background-color: ivory; }
    canvas{border:1px solid red;}
</style&gt;
<script&gt;
$(function(){

    // known CORS violator
    var src1="http://pp-group.co.uk/wp/wp-content/uploads/2013/10/house-illustration-web.gif";
    // known CORS compliant
    var src2="https://dl.dropboxusercontent.com/u/139992952/houseIcon.png";

    // callbacks depending on if the image causes tainted canvas
    function tainted(img){console.log("tainted:",img.src);}
    function notTainted(img){console.log("not tainted:",img.src);}

    // testing
    var image1=newImage(src1,tainted,notTainted);
    var image2=newImage(src2,tainted,notTainted);


    function newImage(src,callWhenTainted,callWhenNotTainted){

        // tmpCanvas to test CORS
        var tmpCanvas=document.createElement("canvas");
        var tmpCtx=tmpCanvas.getContext("2d");
        // tmpCanvas just tests CORS, so make it 1x1px
        tmpCanvas.width=tmpCanvas.height=1;

        var img=new Image();
        // set the cross origin flag (and cross our fingers!)
        img.crossOrigin="anonymous";
        img.onload=function(){
            // add a tainted property to the image 
            // (initialize it to true--is tainted)
            img.tainted=true;
            // draw the img on the temp canvas
            tmpCtx.drawImage(img,0,0);
            // just in case this onload stops on a CORS error...
            // set a timer to call afterOnLoad shortly
            setTimeout(function(){
                afterOnLoad(img,callWhenTainted,callWhenNotTainted);
            },1000);  // you can probably use less than 1000ms
            // try to violate CORS
            var i=tmpCtx.getImageData(1,1,1,1);
            // if we get here, CORS is OK so set tainted=false
            img.tainted=false;
        };
        img.src=src;
        return(img);
    }

    // called from image.onload
    // at this point the img.tainted flag is correct
    function afterOnLoad(img,callWhenTainted,callWhenOK){
        if(img.tainted){
            // it's tainted
            callWhenTainted(img);
        }else{
            // it's OK, do dataURL stuff
            callWhenOK(img);
        }
    }


}); // end $(function(){});
</script&gt;
</head&gt;
<body&gt;
    <canvas id="canvas" width=360 height=281&gt;</canvas&gt;
</body&gt;
</html&gt;
```

Comment for this answer: Just in case it was not clear to readers, this is still throwing an uncaught error, it is just ignored by synchronous code because it throws in the asynchronous flow. In some environments uncaught asynchronous exceptions will halt the program (and you should catch them regardless).

{'source': 'StackExchangeDataset', 'subset': 'stackoverflow.com', 'metadata': {'AnswerCount': 2, 'CommentCount': 4, 'ContentLicense': 'CC BY-SA 3.0', 'CreationDate': '2014:00:03/22/14', 'FavoriteCount': 3.0, 'PostTypeId': 1, 'Tags': '<javascript><html5-canvas><cors>', 'Title': 'How to check, if a canvas element has been tainted?', 'ViewCount': 6761, 'id': 22575636, 'user_AboutMe': '<p>Researcher @<br>\n<a href="http://www.dlr.de/en/" rel="nofollow noreferrer">German Aerospace Center (DLR)</a> <br>\n<a href="http://www.dlr.de/dw/en/" rel="nofollow noreferrer">Insitute of Data Science</a> <br>\nGroup for Data Management and Analysis</p>\n', 'user_AccountId': 1198635.0, 'user_DisplayName': 'Sirko', 'user_Reputation': 70542.0, 'user_Views': 4638.0, 'user_id': 1169798.0}}