在 Cloudfront 上设置 Access-Control-Allow-Origin

Ton*_*ony 22 firefox amazon-s3 amazon-cloudfront amazon-web-services cors

我在使用 AWS Cloudfront 向 Firefox 提供静态资产时遇到问题。

Chrome 运行良好,但 Firefox 返回 CORS 错误。

如果我执行 curl ,我会得到:

HTTP/1.1 200 OK
Content-Type: application/x-font-opentype
Content-Length: 39420
Connection: keep-alive
Date: Mon, 11 Aug 2014 21:53:50 GMT
Cache-Control: public, max-age=31557600
Expires: Sun, 09 Aug 2015 01:28:02 GMT
Last-Modified: Fri, 08 Aug 2014 19:28:05 GMT
ETag: "9df744bdf9372cf4cff87bb3e2d68fc8"
Accept-Ranges: bytes
Server: AmazonS3
Age: 2743
X-Cache: Hit from cloudfront
Via: 1.1 c445b20dfbf3128d810e975e5d84e2cd.cloudfront.net (CloudFront)
X-Amz-Cf-Id: ...
Run Code Online (Sandbox Code Playgroud)

我认为需要标题:

Access-Control-Allow-Origin: *
Run Code Online (Sandbox Code Playgroud)

谁能帮我?为什么它是 Firefox 而不是 Chrome 的问题?我该如何解决?

小智 21

首先,您需要确保将原始标头列入白名单:

如果您希望 CloudFront 遵守跨源资源共享设置,请将 CloudFront 配置为将 Origin 标头转发到您的源。

http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html#request-custom-cors

另请参阅:http : //aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/

顺便说一句,关于 serverfault/stackoverflow 有几个类似的问题和很多答案。


Ras*_*sen 14

这比接受的答案所表明的要复杂一些。

该CORS支持在使用的Cloudfront + S3在S3中实际执行,它的工作原理是这样根据亚马逊:

请求的 Origin 标头必须与 AllowedOrigin 元素匹配。

如果预检 OPTIONS 请求必须是 AllowedMethod 元素之一,则请求方法(例如,GET 或 PUT)或 Access-Control Request-Method 标头。

预检请求的请求的 Access-Control-Request-Headers 标头中列出的每个标头都必须与 AllowedHeader 元素匹配。

可能不清楚的是,如果客户端没有发送 Origin 头,那么这个处理就不会发生。我们在前面使用 Cloudfront,如果您只是托管静态资产,您可能已经设置为忽略所有标头。结果是,如果来自特定边缘节点的每个文件的第一个请求不包含 Origin 标头,它将缓存没有 Access-Control-Allow-Origin 标头的响应,从而导致 CORS 失败。

结果是第一个传入请求将确定所有请求返回哪些标头,直到缓存过期。

有办法解决/解决这个问题。

  • 根据“Origin”标头启用条件缓存。

如果您只期望几个或一个来源,这可以正常工作,但否则您的缓存率可能会变得非常糟糕。

  • 使用 Lambda@edge 强制设置标头,这可以为每个源 (S3) 请求只设置一次。

完全灵活,但会增加开销和成本。

  • 将“Origin”标头覆盖为每个请求的虚拟值。

这是通过在“Origin Custom Headers”中插入一些随机域名来完成的。像“example.org”这样的任何东西都可以正常工作,这将导致 S3 处理始终运行,如果配置正确,S3 将返回“Access-Control-Allow-Origin:*”。

这仅在“Access-Control-Allow-Origin:*”情况下才真正有用,它有点黑客,但它可能是在 cloudfront + S3 上托管静态资产时最好的当前解决方案。