Firefox 不呈现来自 CloudFront 的字体

Posted

技术标签:

【中文标题】Firefox 不呈现来自 CloudFront 的字体【英文标题】:Firefox does not render fonts from 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 返回没有字体的字体...为什么没有加载字体? 提前致谢。

【问题讨论】:

【参考方案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://***.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>

【讨论】:

你在使用云端吗? 糟糕,抱歉。 assets-p.artcat.com/file_uploads/file_asset/asset/… 的 CSS 文件是从 Cloudfront 加载的,但字体似乎是从 S3 加载的。我认为我们无法通过云端使其工作。 这是 S3 存储桶上的 CORS 文件,提供字体 gist.github.com/bhoggard/7477688

以上是关于Firefox 不呈现来自 CloudFront 的字体的主要内容,如果未能解决你的问题,请参考以下文章

来自 Cloudfront 的 HIT 后来自 Cloudfront 的 MISS

在正文标记的末尾呈现阻塞 Javascript - Firefox 呈现一些视觉内容,Chrome 不呈现

如何强制 Cloudfront 将来自源的所有请求强制为 HTTPS?

无法在 Safari 中加载跨域图像(来自 CloudFront)

不希望图像加载和 CSS 在 Selenium WebDriver 中的 Firefox 上呈现 - Python

来自 S3 Origin 的 Cloudfront 响应不断更改 CORS 标头