15

我有一个在 pixie.strd6.com 上运行的站点,以及通过 Amazon S3 托管的图像,其 CNAME 为 images.pixie.strd6.com。

我希望能够将这些图像绘制到 HTML5 画布上并调用 getImageData 方法,但它会抛出Error: SECURITY_ERR: DOM Exception 18

我试过设置window.domain = "pixie.strd6.com",但没有效果。

此外,$.get("http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982", function(data) {console.log(data)})还会引发错误:XMLHttpRequest cannot load http://dev.pixie.strd6.com/sprites/8516/thumb.png?1293830982. Origin http://pixie.strd6.com is not allowed by Access-Control-Allow-Origin.

理想情况下,HTML5 画布不会阻止getImageData来自子域的调用。我已经研究过在 S3 中设置 Access-Control-Allow-Origin 标头,但没有成功。

非常感谢任何帮助或解决方法。

4

9 回答 9

6

亚马逊最近宣布支持 CORS

我们很高兴地宣布在 Amazon S3 中支持跨域资源共享 (CORS)。您现在可以轻松构建使用 JavaScript 和 HTML5 与 Amazon S3 中的资源交互的 Web 应用程序,使您能够将 HTML5 拖放上传到 Amazon S3、显示上传进度或更新内容。到目前为止,您需要在 Web 应用程序和 Amazon S3 之间运行自定义代理服务器来支持这些功能。

如何启用 CORS

要将您的存储桶配置为允许跨域请求,您需要创建一个 CORS 配置、一个 XML 文档,其中包含用于识别您将允许访问您的存储桶的源的规则、将支持每个源的操作(HTTP 方法)以及其他操作-具体信息。您最多可以向配置添加 100 条规则。您将 XML 文档作为 cors 子资源添加到存储桶。

于 2012-11-02T17:30:39.857 回答
4

一种可能的解决方案是使用 nginx 作为代理。下面是如何配置 url 去 http://pixie.strd6.com/s3/传递到 S3,但是浏览器仍然可以认为它是非跨域的。

location /s3/ {
  proxy_pass http://images.pixie.strd6.com/;
}
于 2011-02-05T09:04:48.600 回答
3

如果您使用的是 PHP,您可以执行以下操作:

    function fileExists($path){
        return (@fopen($path,"r")==true);
    }
    $ext = explode('.','https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg');
    if(fileExists('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg')){
        $contents = file_get_contents('https://cgdev-originals.s3.amazonaws.com/fp9emn.jpg');
        header('Content-type: image/'.end($ext));
        echo $contents;
    }

并使用该 php 文件访问图像,例如,如果文件名为 generateImage.php,您可以执行<img src="http://GENERATEPHPLOCATION/generateImage.php"/>此操作,并且外部图像 url 可以是文件的获取参数

于 2012-06-27T19:53:15.940 回答
2

最近,我遇到$.getImageData了 Max Novakovic 的作品。该页面包括几个关于获取和操作 Flickr 照片的简洁演示,以及一些代码示例。

它允许您从任意站点以 JavaScript 可操作的形式获取图像。它通过将脚本附加到页面来工作。然后该脚本从 Google App Engine 服务器请求图像。服务器获取请求的图像并将其转换为 base64 到脚本。当脚本接收到 base64 时,它会将数据传递给回调,然后回调可以将其绘制到画布上并开始处理它。

于 2011-03-07T04:58:53.253 回答
2

过去,Amazon S3 不允许您修改或添加 access-control-allow-origin 和 access-control-allow-credentials HTTP 标头,因此最好切换到 Rackspace Cloud Files 之类的其他服务或一些其他服务。

添加或修改 HTTP 标头,如下所示:

access-control-allow-origin: [your site]
access-control-allow-credentials: true

有关更多信息,请参见http://www.w3.org/TR/cors/#use-cases

使用允许您修改 HTTP 标头的服务可以完全解决同源问题。

于 2012-02-15T04:54:04.577 回答
2

对于不使用 S3 的人,可以尝试构建一个图像代理,对图像文件进行编码并将其包装到 JSON 对象中。

然后您可以使用支持跨域的 JSONP 来获取 JSON 对象并将图像数据分配给 img.src 。

我使用 Google App Engine 编写了图像代理服务器的示例代码。 https://github.com/flyakite/gae-image-proxy

JSON 对象以如下格式返回

{ 
  'height': 50, 
  'width' : 50, 
  'data'  : 'data:image/jpeg;base64,QWRarjgk4546asd...QWAsdf'
} 

'data' 是 base64 格式的图像数据。将其分配给图像。

img.src = result.data;

图像现在对于您的画布来说是“干净的”。

于 2013-03-27T12:14:04.757 回答
2

要编辑您的 S3 存储桶权限:

1) 登录 AWS 管理控制台并在https://console.aws.amazon.com/s3/打开 Amazon S3 控制台

2) 在 Buckets 列表中,打开要查看其属性的 Bucket,然后点击“添加 CORS 配置”

亚马逊屏幕截图

3)写下你愿意在标签之间添加的规则<CORSConfiguration>

<CORSConfiguration>
  <CORSRule>
    <AllowedOrigin>*</AllowedOrigin>
    <AllowedMethod>GET</AllowedMethod>
    <MaxAgeSeconds>3000</MaxAgeSeconds>
    <AllowedHeader>*</AllowedHeader>
  </CORSRule>
</CORSConfiguration>

您可以在以下位置了解有关规则的更多信息:http: //docs.aws.amazon.com/AmazonS3/latest/dev/cors.html

4) 在您将在画布中使用的图像上指定 crossorigin='anonymous'

于 2013-11-12T20:13:38.297 回答
1

此行为是设计使然。根据 HTML5 规范,一旦您将跨域图像绘制到画布上,它就会变脏并且您无法再读取像素。源匹配比较方案、完全合格的主机,以及在非 IE 浏览器中的端口。

于 2011-01-12T18:46:12.647 回答
1

刚刚碰到同样的问题。我发现了可能有用的 CORS。

http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#14

它对我不起作用,因为我试图操纵来自 Flickr 的图像。所以,我仍在寻找解决方案。

于 2011-12-12T15:17:24.433 回答