3

我以为我已经找到了解决 Firefox 和 CDN 托管字体访问这个非常棘手的问题的方法,但是 IE9 来了。

我最近发现了一个非常令人沮丧的 IE9 缓存问题,并且偶然看到了这篇博文(IE9 Redirect Caching Nightmare),它让我对实际问题有了更多的了解。

我不得不承认我不确定上面提到的是否真的是问题,但它似乎足够接近。

问题:

我有一个网站设置有 2 个域(基域和子域)指向同一服务器,提供完全相同的网站,该网站使用由 Cloudfront 提供服务的 Amazon S3 上托管的 CDN 中的同一组资源。

https://example.com
https://www.example.com

使用@font-face 从我的 CSS 文件加载字体时,我在 IE9 开发人员工具控制台中收到此类错误消息:

CSS3117: @font-face failed cross-origin request. Resource access is restricted.

当我首先加载其中一个 URL,然后访问另一个 URL 时,就会发生这种情况。IE9没有Compatibility Mode. 它运行在Document Mode: IE9 Standards.

根据我对 CORS 的有限理解和设置Access-Control-Allow-OriginHTTP 标头的需要,我尽职尽责地在 S3 CORS 策略中设置了它,并且它在 Firefox 上运行得非常好。

来自两个域的请求在请求 CDN 资源时将获得各自的标头。

似乎 IE9 尝试对缓存进行一些优化,并缓存了重定向。这会导致问题,因为Access-Control-Allow-Origin标头也被缓存。如果不向 CDN 服务器发送请求,则Access-Control-Allow-Origin不同域的标头无法更改。

因此,我遇到了请求来自https://www.example.comAccess-Control-Allow-Originis的情况https://example.com。这会导致上述错误消息的资源受限问题。

进一步看:我用Firefox 19做了一个检查,确实出现了上述情况,但是没有遇到和IE9一样严格的限制。https://www.example.com请求信息的子域 ( ) 将接受access-control-allow-origin主域 ( https://example.com) 的。Chrome (Webkit) 似乎并不在意。我不知道哪个浏览器的行为实现是正确的。

根据我在 CDN 中的当前设置,Chrome 和 Firefox 似乎会自动将所有www子域请求重新路由到主域。只有多次尝试www在地址栏中输入子域,Chrome 和 Firefox 才会服从。另一方面,IE9 只会转到地址栏中输入的任何地址。IE9 似乎是奇怪的,但我不确定哪个浏览器的行为实际上是正确的。

从可用性的角度来看,Chrome 和 Firefox 似乎是“正确”的行为。

已知可能的解决方案:

  1. 设置Access-Control-Allow-Origin标题以允许所有,即*
  2. 在浏览器中关闭缓存
  3. 将一个域重定向到另一个域
  4. 使用查询字符串区分资源的不同域调用
  5. 将字体作为 data-uri 嵌入到 CSS 中

对于解决方案 1,假设我很偏执,只想设置特定域以允许。

对于解决方案 2,如果我要为所有浏览器设置它并不是最佳选择,而且我的网站必须在通常低于理想下载速度的移动设备上运行。

对于解决方案 3,可能,但我仍然对直接处理 IE9 缓存问题的解决方案感到好奇。

对于解决方案 4,实现起来非常困难,尤其是从@font-face. 这是否意味着我必须为不同行的不同域调用动态重新生成 CSS 才能加载字体以绕过问题?似乎违背了 CSS 本身的目的,并为此缓存资源。

编辑:样式表有效,字体加载无效。

对于解决方案5,维护和更新非常繁琐,特别是在字体文件定期更改时。

问题:在这种特殊情况下,是否有任何已知的方法来专门处理 IE9 的重定向缓存行为?

非常感谢您的回答和评论。提前致谢!

编辑:更多浏览器测试信息。

4

2 回答 2

0

我们在 IE10 和 IE11 中也发现了同样的奇怪行为。

重置浏览器缓存可以毫无问题地加载字体。还启用和禁用兼容模式。

但是当切换到另一个子域时,IE 不会渲染字体,因为请求头与响应头不匹配,响应头仍然是最后一个请求的 URL。即使存储桶上的定义是 *.ourdomain.com,IE 也会始终显示完整的 URL

因此,通过向 S3 存储桶添加 CORS 权限解决了允许对 webfonts 等资产的跨源请求的一般问题——这使得 webfonts 在 Firefox 中完美运行。

但是我们仍然不知道如何避免*并告诉 IE 不要缓存响应头。

于 2014-01-15T13:59:11.357 回答
0

解决方案1: 检查这个问题

解决方案 4:将您的 CSS 文件重命名为 style.php 并使用您需要调用适当资源的任何代码。

在页面顶部设置内容类型。

<?php
    header("Content-type: text/css; charset: UTF-8");
?>

来自 Chris Coyier 的有关 style.php 的更多信息。

于 2013-03-12T22:26:14.793 回答