【发布时间】:2013-02-19 04:25:18
【问题描述】:
我以为我有found a solution to the very vexing problem with Firefox and CDN-hosted fonts access,但是IE9来了。
我最近发现了一个非常令人沮丧的 IE9 缓存问题,偶然发现了这个 blog post (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,然后再访问另一个时,就会发生这种情况。 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 是https://example.com。这会导致上面的错误消息出现资源受限问题。
再看:我用Firefox 19做了检查,确实出现了上述情况,但是没有遇到IE9那样严格的限制。子域 (https://www.example.com) 请求信息将接受主域 (https://example.com) 的 access-control-allow-origin。 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 的重定向缓存行为?
非常感谢答案和 cmets。提前致谢!
编辑:更多浏览器测试信息。
【问题讨论】:
标签: css amazon-s3 internet-explorer-9 font-face cors