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)