可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Did I not get enough sleep or what? This following code
var frame=document.getElementById(\"viewer\");
frame.width=100;
frame.height=100;
var ctx=frame.getContext(\"2d\");
var img=new Image();
img.src=\"http://www.ansearch.com/images/interface/item/small/image.png\"
img.onload=function() {
// draw image
ctx.drawImage(img, 0, 0)
// Here\'s where the error happens:
window.open(frame.toDataURL(\"image/png\"));
}
is throwing this error:
SECURITY_ERR: DOM Exception 18
There\'s no way this shouldn\'t work! Can anyone explain this, please?
回答1:
In the specs it says:
Whenever the toDataURL() method of a
canvas element whose origin-clean flag
is set to false is called, the method
must raise a SECURITY_ERR exception.
If the image is coming from another server I don\'t think you can use toDataURL()
回答2:
Setting cross origin attribute on the image objects worked for me (i was using fabricjs)
var c = document.createElement(\"img\");
c.onload=function(){
// add the image to canvas or whatnot
c=c.onload=null
};
c.setAttribute(\'crossOrigin\',\'anonymous\');
c.src=\'http://google.com/cat.png\';
For those using fabricjs, here\'s how to patch Image.fromUrl
// patch fabric for cross domain image jazz
fabric.Image.fromURL=function(d,f,e){
var c=fabric.document.createElement(\"img\");
c.onload=function(){
if(f){f(new fabric.Image(c,e))}
c=c.onload=null
};
c.setAttribute(\'crossOrigin\',\'anonymous\');
c.src=d;
};
回答3:
If the image is hosted on a host that sets either of Access-Control-Allow-Origin or Access-Control-Allow-Credentials, you can use Cross Origin Resource Sharing (CORS). See here (the crossorigin attribute) for more details.
Your other option is for your server to have an endpoint that fetches and serves an image. (eg. http://your_host/endpoint?url=URL)
The downside of that approach being latency and theoretically unnecessary fetching.
If there are more alternate solutions, I\'d be interested in hearing about them.
回答4:
Seems there is a way to prevent that if image hosting able to provide the following HTTP headers for the image resources and browser supports CORS:
access-control-allow-origin: *
access-control-allow-credentials: true
It is stated here: http://www.w3.org/TR/cors/#use-cases
回答5:
I had the same problem and all the images are hosted in the same domain... So, if someone is having the same problem, here is how I solved:
I had two buttons: one to generate the canvas and another one to generate the image from the canvas. It only worked for me, and sorry that I don\'t know why, when I wrote all the code on the first button. So when I click it generate the canvas and the image at the same time...
I always have this security problem when the codes were on different functions... =/
回答6:
Finally i found the solution. Just need add the crossOrigin
as third param in fromURL
func
fabric.Image.fromURL(imageUrl, function (image) {
//your logic
}, { crossOrigin: \"Anonymous\" });
回答7:
You can\'t put spaces in your ID
Update
My guess is that image is on a different server than where you\'re executing the script. I was able to duplicate your error when running it on my own page, but it worked fine the moment I used an image hosted on the same domain. So it\'s security related - put the image on your site. Anyone know why this is the case?
回答8:
I was able to make it work using this:
Write this on first line of your .htaccess
on your source server
Header add Access-Control-Allow-Origin \"*\"
Then when creating an <img>
element, do it as follows:
// jQuery
var img = $(\'<img src=\"http://your_server/img.png\" crossOrigin=\"anonymous\">\')[0]
// or pure
var img = document.createElement(\'img\');
img.src=\'http://your_server/img.png\';
img.setAttribute(\'crossOrigin\',\'anonymous\');
回答9:
If you are simply drawing some images on a canvas, make sure you are loading the images from the same domain.
www.example.com is different to example.com
So make sure your images and the url you have in your address bar are the same, www or not.
回答10:
I\'m using fabric.js and could resolve this by using toDatalessJSON instead of toDataURL:
canvas.toDatalessJSON({ format: \'jpeg\' }).objects[0].src
Edit: Nevermind. This results in just the background image being exported to JPG, without the drawing on top so it was not entirely useful after all.