我有一个 Rails 应用,托管在 Heroku 上。在部署期间,资产通过asset_sync
gem与 Amazon S3 存储桶同步,并且视图通过 CloudFront 调用这些资产。但是,使用 Firefox 查看网站时不会呈现字体(文件在Firebug的Net选项卡中加载,但根本不使用)。 Safari很棒。
我在S3上有以下 CORS 配置:
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Content-*</AllowedHeader>
<AllowedHeader>Host</AllowedHeader>
</CORSRule>
</CORSConfiguration>
我的应用还会设置以下标题:
Access-Control-Allow-Origin: *
Access-Control-Request-Method: *
但 CloudFront 会返回没有它们的字体...为什么没有加载字体? 提前谢谢。
答案 0 :(得分:8)
某些版本的Internet Explorer和Firefox会将字体视为攻击媒介,如果它们由其他域提供(跨域策略),则会拒绝加载它们。
在标准 HTTP 服务器上,您需要做的就是添加Access-Control-Allow-Origin: *
标头以绕过CORS策略。问题是 S3 不支持发送它。 (虽然根据规范,它应该支持CORS,但不会发送标头)。
有一种解决方法。 CloudFront可以指向另一个可以发送Access-Control-Allow-Origin
标题的服务器(您可以使用为您的应用;)
提供服务的服务器执行该操作。)
可以通过从 AWS控制台向 CloudFront 分发添加自定义源来完成此操作。接下来,您必须使用字体类型和新添加的 Origin 添加行为。您可以使用通配符作为文件名。 (对于您拥有的每种字体类型,您需要执行一次此操作)。
示例:
Path Pattern: /assets/*.woff
准备就绪后,您可以使用以下命令验证标题是否存在:
curl -I http://cloudfrontid.cloudfront.new/assets/font.woff
希望您会看到您的服务器提供的Access-Control-Allow-Origin
标题以及文件本身, CloudFront 缓存并包含标题。
希望它有所帮助!
答案 1 :(得分:2)
尝试在Cloudfront中使您的(缓存)字体文件无效:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#invalidating-objects-console
今天我遇到了类似的问题。我读了article,建议在CloudFront中缓存CORS配置。我通过使我的字体文件无效来解决我的问题。
答案 2 :(得分:0)
这是我的CORS配置的样子。我有一个与你不同的AllowedHeader。我不使用asset_sync。
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>*</AllowedOrigin>
<AllowedMethod>GET</AllowedMethod>
<MaxAgeSeconds>3000</MaxAgeSeconds>
<AllowedHeader>Authorization</AllowedHeader>
</CORSRule>
</CORSConfiguration>
答案 3 :(得分:0)
2014年6月26日,AWS在CloudFront中添加了对CORS的支持,现在您只需使用CloudFront和S3即可实现此功能。
此SO答案提供有关为特定CloudFront分配启用CORS支持的信息: https://stackoverflow.com/a/24459590/3195497
此外,您需要在S3存储桶上启用CORS。其中一个答案就S3而言:
虽然根据规范它应该支持CORS,但是 标题未发送
从我的测试来看,这只是部分正确。如果在请求中发送Origin
标头,则S3将正确发送Access-Control-Allow-Origin
标头。如果Origin
标题不已发送,则S3将不发送Access-Control-Allow-Origin
标题。
过去,这会导致CloudFront出现问题。如果您在没有Origin
请求标头的情况下向CloudFront发出任何请求,则CloudFront将缓存没有Access-Control-Allow-Origin
响应标头的响应。这可能是因为您使用curl命令测试资产而您没有包含Origin
请求标头。现在,当您使用Origin
标头向CloudFront发出请求时,CloudFront将忽略Origin
标头,并在没有Access-Control-Allow-Origin
标头的情况下提供缓存响应。
通过最近发布到CloudFront的更改,您可以配置您的分发以考虑Origin
请求标头。在这种情况下,CloudFront将缓存不同的响应,对Origin
标头的每个值都有一个响应。