我可以将跨站点 <img/> 标记的数据作为 blob 获取吗?

Yuv*_*val 5 html javascript greasemonkey google-chrome-extension

我正在尝试将网页链接到的几个图像保存到离线存储中。我在 Firefox 上使用 IndexedDB,在 Chrome 上使用 FileSystem API。我的代码实际上是一个扩展,因此在 Firefox 上我在 Greasemonkey 上运行,在 Chrome 上作为内容脚本运行。我希望这是自动化的。

当我检索图像文件时遇到问题。我正在使用标题为在 IndexedDB 中存储图像和文件的文章中的示例代码,但出现错误:我尝试下载的图像位于不同的子域上,并且 XHR 失败。

XMLHttpRequest cannot load http://...uxgk.JPG. Origin http://subdomain.domain.com is not allowed by Access-Control-Allow-Origin.
Run Code Online (Sandbox Code Playgroud)

在 Firefox 上我可能可以使用GM_xmlhttpRequest并且它可以工作(当我位于同源 URL 时,代码在两种浏览器上都可以工作),但我仍然需要解决 Chrome 的问题,其中其他限制(即需要交互)主页上有框架)要求我将我的脚本合并到页面中并放弃我的特权。

所以回到我试图找出一种方法来将链接到(并且可能出现在)页面中的图像保存到 IndexedDB 和/或 FileSystem API。我要么需要了解如何解决 Chrome 中的跨域问题(如果它需要权限,那么我需要修复与 jQuery 交互的方式),要么需要某种反向createObjectURL。归根结底,我需要一个 blob (File对象,据我所知)放入 IndexedDB (Firefox) 或写入 FileSystem API (Chrome)

帮忙,有人吗?


编辑:我的问题实际上可能归结为如何以我想要的方式使用 jQuery,而不失去 Chrome 上的内容脚本权限。如果我这样做,我也可以在 Chrome 上使用跨域 XHR 。尽管我更愿意得到一个不依赖于此的解决方案。具体来说,因为如果我将脚本合并到网页中,并且不要求它是内容脚本/用户脚本,我希望使用此解决方案。


编辑:我意识到问题只是关于跨站点请求现在,在 @chris-sobolewski、这些 问题和其他一些页面(如这样)的帮助下,我有三种方法来获取图像 blob ,可以在这个 fiddle中看到。然而,所有这些都需要特殊权限才能运行。唉,由于我在带有框架的页面上运行,由于Chrome 中的已知缺陷,我无法访问框架。因此,我可以使用 将脚本加载到每个帧中all_frames: true,但我真的想避免在每个帧加载时加载脚本。否则,根据这篇文章,我需要逃离沙箱,但随后又回到特权。

Chr*_*ski 3

由于您在 Chrome 和 Firefox 上运行,幸运的是,您的答案是肯定的(某种程度上)。

function base64img(i){
    var canvas = document.createElement('canvas');
    canvas.width = i.width;
    canvas.height = i.height;
    var context = canvas.getContext("2d");
    context.drawImage(i, 0, 0);
    var blob = canvas.toDataURL("image/png");
    return blob.replace(/^data:image\/(png|jpg);base64,/, "");
}
Run Code Online (Sandbox Code Playgroud)

这将返回 base64 编码的图像。

从那里你只需按照以下方式调用该函数:

image = document.getElementById('foo')
imgBlob = base64img(image);
Run Code Online (Sandbox Code Playgroud)

然后继续存储imgBlob

编辑:由于文件大小是一个问题,您还可以将数据存储为canvasPixelArray,其大小为宽度*高度*4字节。

imageArray = context.getImageData( 0, 0 ,context.canvas.width,canvasContext.canvas.height );
Run Code Online (Sandbox Code Playgroud)

然后将数组 JSONify 并保存?

  • 更新:canvas.toDataURL() 尊重同源策略(http://stackoverflow.com/questions/2390232/why-does-canvas-todataurl-throw-a-security-exception),所以我不能在我的情况下,尽管如果我让 FF 和 Chrome 在这种情况下减轻我的负担,它可能会工作得很好。 (2认同)