Amazon S3 CORS(跨源资源共享)和Firefox跨域字体加载

Firefox不能从当前网页加载不同来源的字体是一个长期存在的问题。 通常,在CDN上提供字体时会出现问题。

其他问题已经提出了各种解决scheme:

CSS @ font-face不适用于Firefox,但是可以使用Chrome和IE

随着Amazon S3 CORS的推出,有没有一种解决scheme使用CORS来解决Firefox中的字体加载问题?

编辑:很高兴看到S3 CORSconfiguration的样本。

编辑2:我find了一个工作解决scheme,却没有真正理解它做了什么。 如果任何人都可以提供关于configuration的更详细的解释和在亚马逊的configuration解释发生的背景魔术,将不胜感激,如nzifnab谁给它的恩惠。

更新2014年9月10日:

您现在不需要再执行任何查询string黑客行为,因为Cloudfront现在可以正确支持CORS。 见http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/和这个答案的更多信息:; https : //stackoverflow.com/a/25305915/308315


好的,我终于得到了使用下面的configuration文件工作的字体,从文档中的示例稍微调整。

我的字体在S3上托pipe,但是由云端控制。

我不知道为什么它的作品,我的猜测可能是需要<AllowedMethod> GET<AllowedHeader> Content-*

如果任何精通Amazon S3 CORSconfiguration的人都能在这方面得到一些启示,那么将不胜感激。

 <?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>https://mydomain.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <AllowedHeader>Content-*</AllowedHeader> <AllowedHeader>Host</AllowedHeader> </CORSRule> <CORSRule> <AllowedOrigin>https://*.mydomain.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <AllowedHeader>Content-*</AllowedHeader> <AllowedHeader>Host</AllowedHeader> </CORSRule> </CORSConfiguration> 

编辑:

有些开发人员面临着CloudfrontcachingAccess-Control-Allow-Origin标题的问题。 AWS工作人员已经在下面的链接( https://forums.aws.amazon.com/thread.jspa?threadID=114646 )中解决了这个问题,评论者是@Jeff-Atwood。

从链接的线程中,build议使用查询string来区分来自不同域的调用,作为解决方法。 我将在这里重现缩短的例子。

使用curl来检查响应标题:

域A:a.domain.com

 curl -i -H "Origin: https://a.domain.com" http://hashhashhash.cloudfront.net/font.woff?https_a.domain.com 

来自域A的响应标题:

 Access-Control-Allow-Origin: https://a.domain.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true X-Cache: Miss from Cloudfront 

域B:b.domain.com

 curl -i -H "Origin: http://b.domain.com" http://hashhashhash.cloudfront.net/font.woff?http_b.domain.com 

来自域B的响应标题:

 Access-Control-Allow-Origin: http://b.domain.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true X-Cache: Miss from Cloudfront 

您会注意到Access-Control-Allow-Origin已经返回了不同的值,这些值通过了Cloudfrontcaching。

经过一些调整后,我似乎得到了这个工作没有查询string破解。 更多信息在这里: http : //docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorS3Origin.html#RequestS3-cors

我要通过我的整个设置,这样很容易看到我做了什么,希望这可以帮助其他人。

背景信息:我正在使用具有asset_sync gem的Rails应用程序将资产置于S3上。 这包括字体。

在S3控制台中,我点击了我的存储桶,属性和'编辑corsconfiguration',在这里: CORS配置按钮

在textarea里面我有这样的东西:

 <?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>https://*.example.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <AllowedHeader>*</AllowedHeader> </CORSRule> </CORSConfiguration> 

然后在Cloudfront面板( https://console.aws.amazon.com/cloudfront/home )中创build了一个发行版,添加了一个指向我的S3存储桶的Origin 添加一个原点

然后添加一个默认path的行为来指向基于S3的原点I设置。 我也做了点击白名单标题,并添加了Origin添加行为和白名单标题

现在发生的是以下情况,我认为是正确的:

1)检查S3标题设置是否正确

 curl -i -H "Origin: https://example.com" https://s3.amazonaws.com/xxxxxxxxx/assets/fonts/my-cool-font.ttf HTTP/1.1 200 OK x-amz-id-2: Ay63Qb5uR98ag47SRJ91+YALtc4onRu1JUJgMTU98Es/pzQ3ckmuWhzzbTgDTCt+ x-amz-request-id: F1FFE275C0FBE500 Date: Thu, 14 Aug 2014 09:39:40 GMT Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true Vary: Origin, Access-Control-Request-Headers, Access-Control-Request-Method Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180 Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT ETag: "98918ee7f339c7534c34b9f5a448c3e2" Accept-Ranges: bytes Content-Type: application/x-font-ttf Content-Length: 12156 Server: AmazonS3 

2)检查Cloudfront使用标题

 curl -i -H "Origin: https://example.com" https://xxxxx.cloudfront.net/assets/fonts/my-cool-font.ttf HTTP/1.1 200 OK Content-Type: application/x-font-ttf Content-Length: 12156 Connection: keep-alive Date: Thu, 14 Aug 2014 09:35:26 GMT Access-Control-Allow-Origin: https://example.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180 Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT ETag: "98918ee7f339c7534c34b9f5a448c3e2" Accept-Ranges: bytes Server: AmazonS3 Vary: Origin X-Cache: Miss from cloudfront Via: 1.1 77bdacfea247b6cbe84dffa61da5a554.cloudfront.net (CloudFront) X-Amz-Cf-Id: cmCxaUcFf3bT48zpPw0Q-vDDza0nZoWm9-_3qY5pJBhj64iTpkgMlg== 

(注意上面是cloudfront的一个小错误,因为这些文件被caching了180秒,但是同样的命中)

3)以不同的来源点击云端(但在CORS上为S3存储Access-Control-Allow-Origin ) – Access-Control-Allow-Origin不会被caching! 好极了!

 curl -i -H "Origin: https://www2.example.com" https://xxxxx.cloudfront.net/assets/fonts/my-cool-font.ttf HTTP/1.1 200 OK Content-Type: application/x-font-ttf Content-Length: 12156 Connection: keep-alive Date: Thu, 14 Aug 2014 10:02:33 GMT Access-Control-Allow-Origin: https://www2.example.com Access-Control-Allow-Methods: GET Access-Control-Max-Age: 3000 Access-Control-Allow-Credentials: true Cache-Control: public, must-revalidate, proxy-revalidate, max-age=180 Last-Modified: Mon, 09 Dec 2013 14:29:04 GMT ETag: "98918ee7f339c7534c34b9f5a448c3e2" Accept-Ranges: bytes Server: AmazonS3 Vary: Origin X-Cache: Miss from cloudfront Via: 1.1 ba7014bad8e9bf2ed075d09443dcc4f1.cloudfront.net (CloudFront) X-Amz-Cf-Id: vy-UccJ094cjdbdT0tcKuil22XYwWdIECdBZ_5hqoTjr0tNH80NQPg== 

请注意,上面的域已成功更改没有查询string破解。

当我更改Origin头部时,似乎在第一个请求上总是有一个X-Cache: Miss from cloudfrontX-Cache: Miss from cloudfront之后我得到了预期的X-Cache: Hit from cloudfront

PS值得注意的是,当curl -I(大写I)不会显示Access-Control-Allow-Origin标题,因为它只是一个HEAD,我做的是让它成为GET并向上滚动。

我的字体正确的服务,直到最后推到Heroku …我不知道为什么,但在CORS通配符允许起源停止工作。 我将所有prepro和pro域添加到桶设置中的CORS策略,现在看起来像这样:

 <CORSConfiguration> <CORSRule> <AllowedOrigin>http://prepro.examle.com</AllowedOrigin> <AllowedOrigin>https://prepro.examle.com</AllowedOrigin> <AllowedOrigin>http://examle.com</AllowedOrigin> <AllowedOrigin>https://examle.com</AllowedOrigin> <AllowedMethod>GET</AllowedMethod> <MaxAgeSeconds>3000</MaxAgeSeconds> <AllowedHeader>Authorization</AllowedHeader> </CORSRule> </CORSConfiguration> 

更新:也添加你的http://localhost:PORT

那么,文档指出,你可以坚持configuration为“Cors子资源在你的桶”。 我把这意味着我将创build一个名为“cors”的文件在我的存储桶的根目录下,但是这不起作用。 最后,我必须login到Amazon S3pipe理区域,并在我的存储桶的properties对话框中添加configuration。

S3可以使用一些更好的文档…

就我而言,我没有在CORSconfiguration中定义XML名称空间和版本。 定义那些工作。

 <CORSConfiguration> 

 <?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> 

有一个更好更简单的方法!

我个人更喜欢使用我的DNS子域来解决这个问题。 如果我的CDN是在cdn.myawesomeapp.com而不是sdf73n7ssa.cloudfront.net之后,那么浏览器不会因为跨域安全问题而发生畸形和阻止它们。

要将您的子域指向您的AWS Cloudfront域,请转至AWS Cloudfront控制面板,select您的Cloudfront分配,并将您的CDN子域input到备用域名(CNAME)字段中。 像cdn.myawesomeapp.com会做的。

现在,您可以转到DNS提供程序(如AWS Route 53),并为cdn.myawesomeapp.com创build一个指向sdf73n7ssa.cloudfront.net的CNAME。

http://blog.cloud66.com/cross-origin-resource-sharing-cors-blocked-for-cloudfront-in-rails/

这个configuration为我工作。 我可以列出对象,检索,更新和删除。

 <?xml version="1.0" encoding="UTF-8"?> <CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"> <CORSRule> <AllowedOrigin>http://localhost:3000</AllowedOrigin> <AllowedMethod>HEAD</AllowedMethod> <AllowedMethod>GET</AllowedMethod> <AllowedMethod>PUT</AllowedMethod> <AllowedMethod>POST</AllowedMethod> <AllowedMethod>DELETE</AllowedMethod> <AllowedHeader>*</AllowedHeader> <ExposeHeader>ETag</ExposeHeader> <ExposeHeader>x-amz-meta-custom-header</ExposeHeader> </CORSRule> </CORSConfiguration> 
 <ifModule mod_headers.c> Header set Access-Control-Allow-Origin: http://domainurl.com </ifModule> 

简单的scheme

重新启动我的弹簧引导应用程序(服务器)解决了我的问题。

我在S3上正确configuration了CORS。 curl是正确的响应与起源标题。 Safari正确地获取字体。 那只是不愿意接受CORS的铬。

不确定究竟是什么造成了这种行为。 必须与If-modified-since有关

当然是。 Firefox支持CORS字体,就像http://dev.w3.org/csswg/css3-fonts/#allowing-cross-origin-font-loading

我遇到了同样的问题。 我不必将CNAME添加到我的CDD,以避免跨域问题…我只需要执行以下操作:

转到您的Bucket属性 – >权限 – >添加更多权限 – > Grantee:Everyone并选中'list'选项。

这是一个graphics例子。 http://i.stack.imgur.com/KOEwy.png

希望完全这将是有用的人。