SECURITY_ERR:关于在Chrome扩展程序中使用getImageData的DOM异常18

时间:2011-04-01 09:15:33

标签: security canvas google-chrome-extension getimagedata

我正在撰写我的第一个Chrome扩展程序。我正在尝试使用jQuery和jQuery Image Desaturate pluginhttp://www.flickr.com页面上的图片进行去饱和处理。

我正在我的background.html中以编程方式加载我的脚本(以及jQuery和插件):

  // On browser action click, we load jQuery and the desaturate plugin, then 
  // call our own flickrnoir.js to desaturate the photo.
  chrome.browserAction.onClicked.addListener(function(tab) {
    chrome.tabs.executeScript(null, { file: "jquery.js" }, function() {
      chrome.tabs.executeScript(null, {file: "jQuery.desaturate.js" }, function() {
        chrome.tabs.executeScript(null, { file: "flickrnoir.js" });
      })
    });
  });

我已在manifest.json中为Flickr页面指定了权限:

"permissions": [
  "tabs", "http://www.flickr.com/", "http://*.static.flickr.com/"
]

这似乎工作正常,例如,我可以将Flickr照片页面上所有div的背景添加为红色,方法是将其添加到flickrnoir.js,然后打开Flickr页面并单击我的扩展按钮:

$("div").css("background-color", "#ff0000");

...所以,我成功加载了jQuery,它可以成功访问和更改http://*.flickr.com/*页面的DOM元素。

但是,当我尝试使用去饱和插件去饱和图像(或实际上是所有图像)时,我遇到了安全错误。我的代码:

$("img").desaturate();

...最终会在运行此行的jQuery.desaturate插件代码中结束:

var imgPixels = canvasContext.getImageData(0, 0, imgW, imgH);

此时,Chrome会引发安全例外:

Uncaught Error: SECURITY_ERR: DOM Exception 18

......这让我陷入了困境。

编辑:好的,所以我猜这是因为页面位于www.flickr.com,而我正在复制到画布的图像位于farm6.static.flickr.com?这违反了跨域政策吗?

我对Chrome扩展程序安全模型或canvas上的跨域限制,或两者如何互动,我真的不熟悉,所以我可以使用任何帮助来理解这一点,但是当然,我的基本问题是 - 如何通过此安全异常并使我的代码正常工作?

2 个答案:

答案 0 :(得分:13)

是的,这是一个安全限制。正如它在specs中所说的那样:

  

每当调用origin-clean标志设置为false的canvas元素的toDataURL()方法时,该方法必须引发SECURITY_ERR异常。

     

每当使用其他正确的参数调用其origin-clean标志设置为false的canvas元素的2D上下文的getImageData()方法时,该方法必须引发SECURITY_ERR异常。

     

每当canvas元素的2D上下文的measureText()方法最终使用的原点与拥有canvas元素的Document对象的原点不同时,该方法必须引发SECURITY_ERR异常

当我处理类似的扩展时,我所做的是将图像URL从内容脚本传递到后台页面并在那里进行所有画布操作,然后将画布转换为数据URL并将其发送回内容脚本:

//background.html:
function adjustImage(src, tab) {
    var img = new Image();
    img.onload = function() {
            var canvas = Pixastic.process(img);

            chrome.tabs.sendRequest(tab.id, {cmd: "replace", data: canvas.toDataURL()});
    };
    img.src = src;
}

答案 1 :(得分:0)

所以我也正在开发一个扩展,我希望使用来自跨域获取图像的图像数据,我发现这是可能的!(没有任何时髦的背景页面消息传递)

@Serg, 事实证明,在网页中你不能做跨域的东西,但是,经过一些进一步的挖掘,我发现在chrome扩展中,你可以!

它的主旨是,您所要做的就是在清单中对Cross-Origin XMLHttpRequests请求权限。

{
  "name": "My extension",
  ...
  "permissions": [
    "http://www.google.com/"
  ],
  ...
}

有关详情(特别是如何保持安全),请阅读this