我以为我已经找到了解决 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-Origin
HTTP 标头的需要,我尽职尽责地在 S3 CORS 策略中设置了它,并且它在 Firefox 上运行得非常好。
来自两个域的请求在请求 CDN 资源时将获得各自的标头。
似乎 IE9 尝试对缓存进行一些优化,并缓存了重定向。这会导致问题,因为Access-Control-Allow-Origin
标头也被缓存。如果不向 CDN 服务器发送请求,则Access-Control-Allow-Origin
不同域的标头无法更改。
因此,我遇到了请求来自https://www.example.com
但Access-Control-Allow-Origin
is的情况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 似乎是“正确”的行为。
已知可能的解决方案:
- 设置
Access-Control-Allow-Origin
标题以允许所有,即*
- 在浏览器中关闭缓存
- 将一个域重定向到另一个域
- 使用查询字符串区分资源的不同域调用
- 将字体作为 data-uri 嵌入到 CSS 中
对于解决方案 1,假设我很偏执,只想设置特定域以允许。
对于解决方案 2,如果我要为所有浏览器设置它并不是最佳选择,而且我的网站必须在通常低于理想下载速度的移动设备上运行。
对于解决方案 3,可能,但我仍然对直接处理 IE9 缓存问题的解决方案感到好奇。
对于解决方案 4,实现起来非常困难,尤其是从@font-face
. 这是否意味着我必须为不同行的不同域调用动态重新生成 CSS 才能加载字体以绕过问题?似乎违背了 CSS 本身的目的,并为此缓存资源。
编辑:样式表有效,字体加载无效。
对于解决方案5,维护和更新非常繁琐,特别是在字体文件定期更改时。
问题:在这种特殊情况下,是否有任何已知的方法来专门处理 IE9 的重定向缓存行为?
非常感谢您的回答和评论。提前致谢!
编辑:更多浏览器测试信息。