Amazon S3 CORS(跨域资源共享)和 Firefox 跨域字体加载

2022-01-15 00:00:00 amazon-s3 cors firefox css font-face

长期以来,Firefox 无法从与当前网页不同的来源加载字体,这是一个长期存在的问题.通常,在 CDN 上提供字体时会出现问题.

There has been a long standing issue with Firefox not loading font from different origin than the current webpage. Usually, the issue arise when the fonts are served on CDNs.

在其他问题中提出了各种解决方案:

Various solutions has been raised in other questions:

CSS @font-face 不支持 Firefox,但支持 Chrome 和 IE

随着 Amazon S3 CORS 的引入,是否有使用 CORS 来解决 Firefox 中字体加载问题的解决方案?

With the introduction of Amazon S3 CORS, is there a solution using CORS to address the font loading issue in Firefox?

很高兴看到 S3 CORS 配置示例.

edit: It would be great to see a sample of the S3 CORS configuration.

edit2:我找到了一个可行的解决方案,但并没有真正理解它的作用.如果有人可以提供有关配置的更详细解释以及亚马逊对配置的解释中发生的背景魔法,我们将不胜感激,就像 nzifnab 为它提供赏金一样.

edit2: I have found a working solution without actually understanding what it did. If anyone could provide more detailed explanations about the configs and the background magic that happens on Amazon's interpretation of the config, it will be greatly appreciated, as with nzifnab who put up a bounty for it.

推荐答案

2014 年 9 月 10 日更新:

Update September 10, 2014:

由于 Cloudfront 现在正确支持 CORS,因此您不再需要执行以下任何查询字符串破解.请参阅 http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/ 和这个答案了解更多信息:https://stackoverflow.com/a/25305915/308315

You shouldn't need to do any of the query string hacks below anymore since Cloudfront properly supports CORS now. See http://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/ and this answer for more info: https://stackoverflow.com/a/25305915/308315

好的,我终于通过文档中的示例进行了一些调整,使用下面的配置使字体正常工作.

OK, I finally got the fonts working using the config below with a little tweak from examples in the documentation.

我的字体托管在 S3 上,但前端是 cloudfront.

My fonts are hosted on S3, but fronted by cloudfront.

我不确定它为什么会起作用,我的猜测可能是 <AllowedMethod> GET<AllowedHeader> Content-* 是必需的.

I'm not sure why it works, my guess is probably that the <AllowedMethod> GET and <AllowedHeader> Content-* is needed.

如果任何精通 Amazon S3 CORS 配置的人能够对此有所了解,我们将不胜感激.

If anyone proficient with Amazon S3 CORS config can shed some lights on this, it'll be greatly appreciated.

<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
    <CORSRule>
        <AllowedOrigin>https://mydomain.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
    <CORSRule>
        <AllowedOrigin>https://*.mydomain.com</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Content-*</AllowedHeader>
        <AllowedHeader>Host</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

一些开发人员面临 Cloudfront 缓存 Access-Control-Allow-Origin 标头的问题.AWS 工作人员已在链接 (https://forums.aws.amazon.com/thread.jspa?threadID=114646),由@Jeff-Atwood 评论.

Some developers are facing issues of Cloudfront caching the Access-Control-Allow-Origin header. This issue has been addressed by the AWS staff in the link (https://forums.aws.amazon.com/thread.jspa?threadID=114646) below, commented by @Jeff-Atwood.

从链接的线程中,作为一种解决方法,建议使用 查询字符串 来区分来自不同域的调用.我将在此处重现缩短的示例.

From the linked thread, it is advised, as a workaround, to use a Query String for differentiating between calls from different domains. I'll reproduce the shortened example here.

使用 curl 检查响应头:

域 A:a.domain.com

Domain A: a.domain.com

curl -i -H "Origin: https://a.domain.com" http://hashhashhash.cloudfront.net/font.woff?https_a.domain.com

来自域 A 的响应标头:

Response headers from Domain A:

Access-Control-Allow-Origin: https://a.domain.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
X-Cache: Miss from Cloudfront

域 B:b.domain.com

Domain B: b.domain.com

curl -i -H "Origin: http://b.domain.com" http://hashhashhash.cloudfront.net/font.woff?http_b.domain.com

来自域 B 的响应标头:

Response headers from Domain B:

Access-Control-Allow-Origin: http://b.domain.com
Access-Control-Allow-Methods: GET
Access-Control-Max-Age: 3000
Access-Control-Allow-Credentials: true
X-Cache: Miss from Cloudfront

您会注意到 Access-Control-Allow-Origin 返回了不同的值,这些值通过了 Cloudfront 缓存.

You will notice the Access-Control-Allow-Origin has returned different values, which got past the Cloudfront caching.

相关文章