【问题标题】:Firefox does not render fonts from CloudFrontFirefox 不呈现来自 CloudFront 的字体
【发布时间】:2013-10-01 03:02:43
【问题描述】:

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

【问题讨论】:

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


    【解决方案1】:

    某些版本的 Internet Explorer 和 Firefox 将字体视为攻击媒介,如果它们是由另一个域提供的(跨域策略),则会拒绝加载它们。

    在标准 HTTP 服务器上,您只需添加 Access-Control-Allow-Origin: * 标头即可绕过 CORS 策略。问题是 S3 不支持发送。 (虽然根据规范它应该支持 CORS,但不发送标头)。

    有一个解决方法。 CloudFront 可以指向可以发送 Access-Control-Allow-Origin 标头的另一台服务器(您可以使用为您的应用程序提供服务的服务器来做到这一点 ;) )。

    这可以通过从 AWS 控制台Custom Origin 添加到您的 CloudFront 分配来完成。接下来,您必须使用您的字体类型和新添加的 Origin 添加 Behaviours。您可以使用通配符作为文件名。 (您需要为您拥有的每种字体类型执行一次此操作)。

    例子:

    Path Pattern: /assets/*.woff
    

    准备就绪后,您可以使用以下方法验证标头是否存在:

    curl -I http://cloudfrontid.cloudfront.new/assets/font.woff
    

    希望您会看到 您的服务器 提供的 Access-Control-Allow-Origin 标头以及文件本身,由 CloudFront 缓存并包含标头。

    希望对你有帮助!

    【讨论】:

    • 我没有尝试过,但我认为这会奏效。问题是 Cloudfront 中的自定义来源是 600 美元/月,如果您想将它们与 https 一起使用 :(
    【解决方案2】:

    尝试使 Cloudfront 中的(缓存的)字体文件无效:http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Invalidation.html#invalidating-objects-console

    我今天遇到了类似的问题。我读到article 建议的 CORS 配置缓存在 CloudFront 中。我通过使字体文件无效解决了我的问题。

    【讨论】:

    • 但我的文件是在每次部署时使用新名称后缀生成的。即使部署了“新”字体,问题仍然存在。
    【解决方案3】:

    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 标头的每个值对应一个响应。

    【讨论】:

      【解决方案4】:

      这就是我的 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>
      

      【讨论】:

      猜你喜欢
      • 2014-05-22
      • 1970-01-01
      • 2017-11-04
      • 1970-01-01
      • 2012-10-27
      • 2018-05-21
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多