2012-06-01 21 views
2

所以我有以下代码:的JavaScript HTML5的drawImage与来自不同域的图像

var element = document.getElementById("myCanvas"); 
var width = element.width;         
var height = element.height; 
var context = element.getContext("2d");      

/* test 1 */ 
var img1 = new Image(width, height); 
img1.src = "http://www.mydomain.com/image.jpg"; 

document.body.appendChild(img1);   // <-- A: this works 
context.drawImage(img1,0,0,width,height); // <-- B: this works 

/* test 2 */ 
var img2 = new Image(width, height); 
img2.src = "http://www.notmydomain.com/image.jpg"; 

document.body.appendChild(img2);   // <-- C: this works 
context.drawImage(img2,0,0,width,height); // <-- D: this does not work 

好了,所以在看我的代码,在test 1我创建一个图像对象与被在同一个域托管图片作为我的页面。从A:我可以看到它加载正常(A:C:只是作为测试以确保img对象加载正确)。而且B:也适用,它将图像绘制到我的画布上。

test 2中,我加载托管在与我的网页域不同的域上的图像。 C:工作正常,我知道你可以加载托管在其他域的图像。但是,D:不起作用。我得到以下错误:

Error: uncaught exception: [Exception... "Security error" code: "1000" nsresult: "0x805303e8 (NS_ERROR_DOM_SECURITY_ERR)" location: ....

,从我的理解是指该算作跨站点脚本。

所以这里的问题:

1)为什么这被认为是跨站点脚本?我的意思是,我知道为什么 ......但为什么D:不允许,当C:是?国际海事组织他们在原则/精神上都是一样的东西?

2)有没有办法解决这个问题,而不是传统的跨站脚本解决方法?我想我将不得不使用AJAX将URL传递给服务器端脚本并发出请求,然后将该映像保存在服务器上并向其返回一个URL以使其位于同一个域中,或者其他(我认为)我可以返回原始的base64编码数据,并使用canvas方法从原始数据构建它。我可以生活在做这些事情之一,但...我有点希望也许我错过了关于HTML5 /帆布的东西(我是新来的!)

回答

3

拿着它。其他事情正在发生。

您绝对可以从不同的域中绘制图像。

下面是在的jsfiddle代码placekitten.com绘制图像:

http://jsfiddle.net/ZZW5V/

你应该尝试用notyourdomain图像的URL替换该提琴代码的URL。它应该仍然有效。

一般而言,您应该始终能够从任何能够从其中成功获取图像的位置将图像绘制到画布上。

在那之后,您不允许做的事情是获取imageData或将画布保存到toDataUrl的PNG。有重要的security reasons为什么这是不允许的。

我的猜测是你正在做某件事违反安全规则之一,而不仅仅是试图画出图像。

+0

aha!先生,你是对的。经过更多的探究,我发现它并不是抛出错误的'.drawImage()',而是后面对'.getImageData()'的调用!好吧,这样做更有意义,与'A:'和'C:'东西更一致。 – slinkhi

2

这是一个安全措施,以防止信息被“偷走”。这与您无法使用AJAX从另一个域中获取页面的原因是一样的。

例如,假设一家银行网站使用图片来显示信用信息。您的代码可能会将该图像加载到页面中,然后将其发送到您的服务器,从而窃取客户端的安全信息。这是一个极端的例子,但是一个有效的例子。

您可以将图像附加到页面上,因为您无法从中获取任何信息。您无法将图像加载到您的javascript中,因为您随后可以使用原始图像数据进行操作和传输。

+0

+1,谢谢你的回应!是的,我知道整个xss歌曲和舞蹈,但没有任何意义,我不能做我在帖子中显示的内容,事实证明,你实际上可以这样做,因为它与原理相同'.appendChild()';脚本实际上进一步失败(见Simon Sarris的回应) – slinkhi

相关问题