13

我有一个Rails应用程序,托管在Heroku上。在部署期间,资产通过gem 与A​​mazon S3存储桶同步,视图通过CloudFront调用这些资产。但是,使用Firefox查看网站时不会呈现字体(文件在 Firebug 的 Net 选项卡中加载,但根本没有使用)。Safari 很好用。asset_sync

我在 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

4 回答 4

8

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

在标准HTTP服务器上,您需要做的就是添加Access-Control-Allow-Origin: *标头以绕过 CORS 策略。问题是S3不支持发送它。(尽管根据规范它应该支持 CORS,但不发送标头)。

有一种解决方法。CloudFront 可以指向可以发送Access-Control-Allow-Origin标头的另一台服务器(您可以使用为您的应用程序提供服务的服务器来执行此操作;))。

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

例子:

Path Pattern: /assets/*.woff

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

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

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

希望能帮助到你!

于 2013-11-17T21:38:25.750 回答
2

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

我今天有一个类似的问题。我读过一篇文章,建议 CORS 配置缓存在 CloudFront 中。我通过使我的字体文件无效来解决我的问题。

于 2013-10-01T16:09:20.617 回答
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>
于 2013-11-14T18:05:02.777 回答
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请求标头。现在,当您使用标头向 CloudFront 发出请求时Origin,CloudFront 将忽略Origin标头并提供不带标头的缓存响应Access-Control-Allow-Origin

随着最近发布到 CloudFront 的更改,您可以配置您的分配以将Origin请求标头考虑在内。在这种情况下,CloudFront 将缓存不同的响应,每个Origin标头值一个响应。

于 2014-07-15T18:44:02.593 回答