admin管理员组

文章数量:1279008

This question has been asked a lot, but I just don't understand why this is happening to me.

Basically, I have a canvas, and an image, and when I try to do this:


var canvas = document.getElementById('somecanvas');
var ctx = canvas.getContext('2d');
var someimage = document.createElement('img');
someimage.setAttribute('src', 'img/someimage.png');
someimage.onload = function(){
    ctx.drawImage(someimage, 0, 0, canvas.width, canvas.height);
    data = ctx.getImageData(0,0,canvas.width,canvas.height);
}

I get the unsightly:

"Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. at HTMLImageElement.someimage.onload"


I should mention that I'm fairly new to pogramming, and even moreso to javascript. Should this be happening when I'm running it from file:\\?

I haven't found anyone having the exact same problem as me, and the explanations people got for the other questions had to do with the server the images were hosted on. But in this case it isn't hosted on a server, so I'm confused as to how it all works. Or rather, doesn't work.

This question has been asked a lot, but I just don't understand why this is happening to me.

Basically, I have a canvas, and an image, and when I try to do this:


var canvas = document.getElementById('somecanvas');
var ctx = canvas.getContext('2d');
var someimage = document.createElement('img');
someimage.setAttribute('src', 'img/someimage.png');
someimage.onload = function(){
    ctx.drawImage(someimage, 0, 0, canvas.width, canvas.height);
    data = ctx.getImageData(0,0,canvas.width,canvas.height);
}

I get the unsightly:

"Uncaught DOMException: Failed to execute 'getImageData' on 'CanvasRenderingContext2D': The canvas has been tainted by cross-origin data. at HTMLImageElement.someimage.onload"


I should mention that I'm fairly new to pogramming, and even moreso to javascript. Should this be happening when I'm running it from file:\\?

I haven't found anyone having the exact same problem as me, and the explanations people got for the other questions had to do with the server the images were hosted on. But in this case it isn't hosted on a server, so I'm confused as to how it all works. Or rather, doesn't work.

Share Improve this question edited Aug 1, 2017 at 18:09 Frits 7,62410 gold badges46 silver badges65 bronze badges asked Aug 1, 2017 at 17:19 AndrewAndrew 411 silver badge4 bronze badges 3
  • Hi Andrew - saying thanks is great, but rather ment your thanks on the answer instead of editing your question. Your reputation is too low for menting in general, however you are allowed to ment on answers in your own question thread. :) – Frits Commented Aug 1, 2017 at 18:12
  • Hello, Frits. Thanks for the heads up. I wanted to thank via ment, however when I hovered over the ment link I noticed it said 'avoid ments like "thanks"' so I got confused and edited instead. – Andrew Commented Aug 1, 2017 at 18:28
  • Not a problem at all, to be pletely honest, the best way to thank someone is upvoting their answer (and accepting if you're the question author), it might seem insignificant if you aren't used to it, but trust me, we live for that upvote ;) (check this link and look at the third bullet point) I definitely won't plain about friendliness though, so thank you for trying! – Frits Commented Aug 1, 2017 at 18:32
Add a ment  | 

2 Answers 2

Reset to default 7

For security reasons, many browsers will plain if you try to do certain things (canvas image drawing among them), if you use a file:// URL.

You really should serve both the page and the images from a local HTTP server in order to avoid those restrictions.

Ah, you've hit the CORS restriction, and I'm guessing here that you're encountering this in Google Chrome, which is notorious for being the most aggressive implementor of this. I've seen this a LOT.

CORS is a protocol, to prevent cross-origin content being inserted into a web page. It not only affects script files (as you might expect, because you don't want anyone to be able to inject malicious scripts into your web page), but also affects such resources as images and fonts.

The reason it affects images, is because malicious individuals discovered that they could use the HTML5 canvas object to copy the contents of your web page to a PNG file, and hoover personal data from that at will.You can imagine what would happen if you were engaging in Internet banking transactions whilst this happened to you!

But, and this is the annoying part you're encountering, stopping such malicious activity also impinges on legitimate uses of cross-origin resources (e.g, keeping all your images in a separate repository).

So how do you get around this?

On Firefox, you shouldn't have a problem. Firefox applies some intelligence to the matter, and recognises that images ing from the same file:// specification as your web page, are not actually cross-origin. It lets these through, so long as they're in the same directory on your hard drive as your web page.

Chrome, on the other hand, is much less permissive. It treats all such accesses as cross-origin, and implements security shutdowns the moment you try using getImageData() and putImageData() on a canvas.

There is a workaround, if you don't want to go to the trouble of installing and configuring your own local web server, but still want to use Chrome and its nice, friendly debugger. You have to create a shortcut, that points to your Chrome executable and runs it when you double click on it, but which starts Chrome up using a special mand line flag:

--allow-file-access-from-files

Save this shortcut, labelling it something like "Chrome Debug Version" to remind you ONLY to use this for debugging your own code (you should never access the Internet proper with weakened security!), and you should be able to debug your code without issues from this point on.

But, if you're going to be doing a lot of debugging of this sort, the better long-term solution, is to install a web server, and configure it to serve up code from your desired directories every time you use the "localhost" URL. This is, I know, tedious and time consuming, and distracts from your desire to get coding, but once it's done, it's done and dusted, and solves your woes permanently.

If you really want to put your programming skills to the test, you could even write your own web server to do the job, using something like the node.js server side framework, but if you're new to JavaScript, that's a task you're better leaving until you have a lot more experience! But once your skills reach that point, doing that is a nice educational exercise that will also solve some of your other woes, once you've worked out how a web server works.

If you run with an established web server, you then, of course, have the fun of deciding which one involves the least headaches. Apache is powerful, but big. Hiawatha is both lightweight and secure, and would be my first choice if it wasn't for the fact that a 64-bit version is still not available (sigh), because the 32-bit version that ran on my old XP box was a joy to use. Nginx I know little about, but some people like it. Caveat emptor and all that.

本文标签: javascriptThe canvas has been tainted by crossorigin data local imageStack Overflow