3

所以我有以下代码:

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:?IMO 他们在原则/精神上是一样的吗?

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

4

2 回答 2

5

拿住。这里正在发生其他事情。

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

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

http://jsfiddle.net/ZZW5V/

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

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

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

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

于 2012-06-01T15:29:23.560 回答
2

这是一种防止信息被“窃取”的安全措施。这与您不能使用 AJAX 从另一个域获取页面的原因相同。

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

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

于 2012-06-01T14:51:31.100 回答