10

我正在编写我的第一个 Chrome 扩展程序。我正在尝试使用 jQuery 和jQuery Image Desaturate 插件对http://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" });
      })
    });
  });

我在我的以下文件中指定了 Flickr 页面的权限manifest.json

"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,或者两者如何交互,所以我可以使用你能给我的任何帮助来理解这一点,但当然,我的基本问题是 - - 我如何克服这个安全异常并让我的代码正常工作?

4

2 回答 2

13

是的,这是一个安全限制。正如它在规格中所说:

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

每当使用其他正确参数调用其 origin-clean 标志设置为 false 的画布元素的 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;
}
于 2011-04-01T15:33:10.707 回答
1

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

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

它的要点是,您所要做的就是在清单中请求跨域 XMLHttpRequests 的权限。

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

有关更多信息(尤其是关于如何保持安全),请阅读

于 2011-08-22T13:16:19.867 回答