Firefox不会从CloudFront渲染字体

时间:2013-09-25 13:29:16

标签: ruby-on-rails firefox heroku amazon-s3 amazon-cloudfront

我有一个 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 会返回没有它们的字体...为什么没有加载字体? 提前谢谢。

4 个答案:

答案 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标头的每个值都有一个响应。