2012-09-10 41 views
40

我在S3应用商店图像,然后代理他们通过的Cloudfront。我很高兴能够使用新的S3 CORS支持,以便我可以使用HTML5画布方法(它具有交叉源策略),但似乎无法正确配置我的S3和Cloudfront。当我尝试将图像转换为画布元素时,仍然遇到“未捕获错误:SECURITY_ERR:DOM异常18”。正确的S3 + Cloudfront CORS配置?

这是我到目前为止有:

S3

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

的Cloudfront

起源

Origin Protocol Policy: Match Viewer 

HTTP Port: 80 

HTTPS Port: 443 

行为

Origin: MY_WEBSITE_URL 

Object Caching: Use Origin Cache Headers 

Forward Cookies: None 

Forward Query Strings: Yes 

有什么我在这里失踪?

UPDATE: 刚试过基于这个问题Amazon S3 CORS (Cross-Origin Resource Sharing) and Firefox cross-domain font loading

仍然没有去改变头来

<AllowedHeader>Content-*</AllowedHeader> 
<AllowedHeader>Host</AllowedHeader> 

UPDATE:更多资讯ON REQUEST

Request 
URL:https://d1r5nr1emc2xy5.cloudfront.net/uploaded/BAhbBlsHOgZmSSImMjAxMi8wOS8xMC8xOC81NC80Mi85NC9ncmFzczMuanBnBjoGRVQ/32c0cee8 
Request Method:GET 
Status Code:200 OK (from cache) 

UPDATE

我想也许我的要求是不正确的,所以我试图让CORS与

img.crossOrigin = ''; 

但随后的图像没有按无法加载,并且出现错误:跨源资源共享策略拒绝了跨源图像加载。

+0

你可以在这里发布你的发布请求吗?就像你的策略和参数在上传到s3时在post请求中传递一样。 –

+0

为什么POST请求与GET请求相反? – kateray

+0

好的,你能提供关于获取请求的信息吗? –

回答

1

不能完全确定你的问题是什么,但:

https://forums.aws.amazon.com/thread.jspa?messageID=377513

回答了我的问题与CORS,S3和的Cloudfront的。

我还发现,水桶内的一些资产将用正确的CORS头返回,有的不会。资产无效后,他们都回来了正确的头,不知道为什么一些必要的无效和其他人并没有因为是在同一时间上传,同一类型同一桶:(

+3

吉姆:你发布的链接应该回答你自己的问题!在无效之后,您会得到不同的结果,可能是因为您有多个AllowedOrigin选项(或*),并且首先缓存了任何Origin头部请求的CloudFront。 – philfreo

3

UPDATE:这不再是真实的近期在CloudFront的。yi​​ppee的变化!见对方回应的细节。我在这里离开这个上下文/历史。

问题

CloudFront的不支持CORS 100%,问题是如何CloudFront的缓存对请求的响应。在此之后,对于同一个URL的任何其他请求都将导致缓存的请求,无论其来源为。关键在于它包含来自原点的响应头。

之前CloudFront的有任何从Origin: http://example.com缓存首先请求具有的响应报头:

Access-Control-Allow-Origin: http://example.com 
Origin: https://example.com

第二请求(请注意,它是HTTPS不HTTP)也具有的响应报头:

Access-Control-Allow-Origin: http://example.com 

因为这就是CloudFront为URL所缓存的内容。这是无效的 - 浏览器控制台(至少在Chrome中)将显示CORS违规消息,事情将会中断。

解决方法

建议的解决办法是使用不同的网址不同的起源。诀窍是附加一个不同的唯一查询字符串,以便每个来源有一个缓存记录。

因此,我们的网址是这样的:

http://.../some.png?http_mysite.com 
https://.../some.png?https_mysite.com 

这类作品,但任何人都可以通过交换查询字符串使您的网站的工作知之甚少。这可能吗?可能不是,但调试这个问题是一个巨大的麻烦。

正确的解决方法是在CORS完全支持CORS之前不使用CloudFront与CORS。

在实践

如果使用CloudFront的用于CORS,有一个后备的时候CORS不将工作的另一种方法。这并不总是一种选择,但现在我用JavaScript动态加载字体。如果基于CORS的CloudFront请求失败,我会回退到服务器端代理服务器的字体(不是交叉原点)。这样,即使CloudFront以某种方式获取了字体的缓存记录,情况仍然继续有效。

+2

+1最新更新说明! –

+2

这可能有所帮助:http://ryanwood.com/2014/09/03/a-chrome-update-breaks-cdn-fonts/ – rassom

93

在2014年6月26日AWS所以现在公布proper Vary: Origin behavior on CloudFront你只是

  1. 设置一个CORS配置为您的S3存储包括

    <AllowedOrigin> * </AllowedOrigin >

  2. 在CloudFront - > Distribution - >此行为的行为,使用“转发标题:白名单”选项并将“原始”标题列入白名单。

  3. 等待约20分钟,同时CloudFront的传播新规则

现在您的CloudFront的分布应该缓存的不同反应(适当CORS标头),针对不同的客户端起源头。

+1

不错。这也看起来像解决了通过HTTP和HTTPS与CORS提供资源的问题。 – Ray

+4

FWIW,我还必须将缓存行为更改为“允许的HTTP方法”,包括OPTIONS。 – welegan

+0

仍然没有工作:( – coiso