javascript html5 使用来自不同域的图像绘制图像

sli*_*khi 3 html javascript xss canvas image-processing

所以我有以下代码:

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
Run Code Online (Sandbox Code Playgroud)

好的,看看我的代码,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 编码数据并使用画布方法从原始数据构建它。我可以忍受做这些事情,但是......我有点希望我可能错过了一些关于 html5/canvas 的东西(我是新手!)

Sim*_*ris 5

拿住。这里还发生了其他事情。

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

以下是 jsfiddle 上从 placekitten.com 绘制图像的代码:

http://jsfiddle.net/ZZW5V/

您应该尝试用 notyourdomain 图像的 url 替换该小提琴代码中的 url。它应该仍然有效。

一般来说,您应该始终能够从能够成功获取图像的任何地方将图像绘制到画布上。

在那之后,你不能做的就是获取画布imageData或将画布保存为带有toDataUrl. 有一些重要的安全原因不允许这样做。

我的猜测是,您正在做一些违反安全规则的事情,而不仅仅是试图绘制图像。