我有一个运行在pixie.strd6.com的网站,图片通过Amazon S3托管,图片为CNAME for 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标头,但还没有成功。
非常感谢任何帮助或解决方法。
答案 0 :(得分:6)
Amazon recently announced CORS support
我们很高兴地宣布支持Amazon S3中的跨源资源共享(CORS)。您现在可以轻松构建使用JavaScript和HTML5与Amazon S3中的资源交互的Web应用程序,使您能够实现HTML5拖放上传到Amazon S3,显示上载进度或更新内容。到目前为止,您需要在Web应用程序和Amazon S3之间运行自定义代理服务器以支持这些功能。
要配置存储桶以允许跨源请求,您需要创建一个CORS配置,一个XML文档,其中包含用于标识允许访问存储桶的来源的规则,操作(HTTP方法)将支持每个源,和其他特定于操作的信息。您最多可以为配置添加100条规则。您将XML文档作为cors子资源添加到存储桶中。
答案 1 :(得分:4)
一种可能的解决方案是使用nginx作为代理。以下是如何配置转到http://pixie.strd6.com/s3/的网址以传递到S3,但浏览器仍然可以认为它是非跨网域。
location /s3/ {
proxy_pass http://images.pixie.strd6.com/;
}
答案 2 :(得分: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"/>
,外部图片网址可以是文件的get参数
答案 3 :(得分:2)
最近,我遇到了马克·诺瓦科维奇的$.getImageData
。该页面包含一些在Flickr照片上获取和操作的简洁演示,以及一些代码示例。
它允许您从任意站点以JavaScript可操作的形式获取图像。它的工作原理是在页面上附加一个脚本。然后,该脚本从Google App Engine服务器请求图像。服务器获取请求的图像并将其转换为base64的中继转发给脚本。当脚本收到base64时,它会将数据传递给回调,然后回调可以将其绘制到画布上并开始搞乱它。
答案 4 :(得分:2)
过去,Amazon S3不允许您修改或添加access-control-allow-origin和access-control-allow-credentials HTTP标头,因此最好切换到Rackspace Cloud等其他服务文件或其他一些服务。
添加或修改HTTP标头,如下所示:
access-control-allow-origin: [your site]
access-control-allow-credentials: true
有关详细信息,请参阅http://www.w3.org/TR/cors/#use-cases。
使用允许您修改HTTP标头的服务完全解决了相同的原始问题。
答案 5 :(得分: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;
图片现在为您的画布“干净”。
答案 6 :(得分:2)
编辑S3存储桶权限:
1)登录AWS管理控制台并在https://console.aws.amazon.com/s3/
打开Amazon S3控制台2)在Buckets列表中,打开要查看其属性的存储桶,然后单击“添加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'
答案 7 :(得分:1)
此行为是按设计进行的。根据HTML5规范,只要将交叉原始图像绘制到画布上,它就会变脏并且您无法再读取像素。 Origin-matching比较方案,完全限定主机,在非IE浏览器中比较端口。
答案 8 :(得分:1)
刚刚碰到同样的问题。我发现了可能有用的CORS。
http://html5-demos.appspot.com/static/html5-whats-new/template/index.html#14
因为我试图操纵Flickr中的图像,所以它对我不起作用。所以,我仍然在寻找解决方案。