在 IE CSS font-face 仅在通过内部链接导航时有效
Posted
技术标签:
【中文标题】在 IE CSS font-face 仅在通过内部链接导航时有效【英文标题】:On IE CSS font-face works only when navigating through inner links 【发布时间】:2012-11-05 02:08:00 【问题描述】:我们的网页设计师创建了一个具有以下字体的 CSS:
@font-face
font-family: 'oxygenregular';
src: url('oxygen-regular-webfont.eot');
src: url('oxygen-regular-webfont.eot?#iefix') format('embedded-opentype'),
url('oxygen-regular-webfont.woff') format('woff'),
url('oxygen-regular-webfont.ttf') format('truetype'),
url('oxygen-regular-webfont.svg#oxygenregular') format('svg');
font-weight: normal;
font-style: normal;
它在 IE 和 Firefix 上运行良好。但是有一个问题:在 IE 上,只有当我使用内部网页链接导航页面时,字体才会正确呈现。如果我点击 Refresh 或 Back 按钮,字体将被默认字体(Times New Roman)替换。
目前该网站使用的是 HTTPS,但在使用 HTTP 时发现了同样的问题。
当我使用内部网站链接导航时,在 IE 开发者工具 (Shift - F12) 的“网络”选项卡中,我看到以下内容:
/Content/oxygen-regular-webfont.eot? GET 200 application/vnd.ms-fontobject
当我使用刷新/返回按钮时,其他字体还有两个条目:
/Content/oxygen-regular-webfont.woff GET 200 application/x-font-woff
/Content/oxygen-regular-webfont.ttf GET 200 application/octet-stream
CSS 文件本身正在以下列方式加载:
/Content/site.css GET 200 text/css
我试图同时删除 woff 和 ttf 所以我有以下内容:
@font-face
font-family: 'oxygenregular';
src: url('oxygen-regular-webfont.eot');
src: url('oxygen-regular-webfont.eot?#iefix') format('embedded-opentype');
font-weight: normal;
font-style: normal;
但 IE 的行为仍然相同(除了它不再下载 woff 和 ttf 之外):在通过 Back/Refresh 导航时显示不正确的后备字体。
如何让 IE 在刷新/返回操作时加载正确的字体?
【问题讨论】:
【参考方案1】:不要将 Vary Request Header 设置为 https
不加载字体
Vary:Accept-Encoding,https
作品
Vary:Accept-Encoding
avoid delayed font loading需要设置缓存头。
【讨论】:
【参考方案2】:我找到了解决此问题的替代解决方案。
我已将字体直接嵌入到样式表中,而不是作为单独的字体文件加载。这在包括 Windows、Mac、ios、android 等在内的所有浏览器中都可以正常工作,并有助于减少网页中的 HTTP 请求数量。
这不需要对标头 Cache-Control 进行任何更改。
@font-face
font-family: '<FONT NAME>';
src: url(data:application/x-font-woff;charset=utf-8;base64,<BASE64_ENCODED>) format('woff'),
url(data:application/x-font-ttf;charset=utf-8;base64,,<BASE64_ENCODED>) format('truetype');
font-weight: normal;
font-style: normal;
您可以在 OS X 或 Linux 中使用内置的 base64 命令进行字体编码。
【讨论】:
【参考方案3】:我刚刚遇到了同样的错误,对于那些想要一个纯粹的解决方案(非精确技术相关)的人:您需要确保您发送的字体标题不是no-cache
。除了之前写的内容之外,实际上还有两个标题可以做到这一点:
"cache-control: no-cache"
和
"pragma: no-cache"
这两个都说浏览器是一样的,第一个是 HTTP1.1 的一部分,第二个是旧的(HTTP1.0)。
现在,解决方案:
如果您真的想提供字体(和其他文件?) 客户端缓存,设置"cache-control" to "max-age=0"
;您可以删除 pragma 标头,它已过时(或将其设置为 "pragma: cache"
)。
如果你真的想要缓存:删除 no-cache
值,并设置适当的 max-age(例如 "cache-control: max-age=3600"
- 一小时缓存)。 Pragma 可以设置为"pragma: cache"
或完全删除。
【讨论】:
【参考方案4】:我找到了一个解决方案,但我看不出它起作用的原因(嗯,只有一个原因 - 它是 IE :D)。
我所做的是将同一个站点放在 Apache 上并再次测试。在 Apache 上,即使使用刷新按钮,字体也能正常工作。然后在网络检查器中,我看到 Apache 为 eot 文件返回 304 而不是 200,它击中了我 - 所以这是缓存问题。我去了我的 ASP.NET 应用程序,果然 - 出于安全原因(同时也是为了避免缓存 AJAX 请求)有人禁用了您可以想象的所有缓存:
// prevent caching for security reasons
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
HttpContext.Current.Response.Cache.SetNoServerCaching();
// do not use any of the following two - they break CSS fonts on IE
HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
HttpContext.Current.Response.Cache.SetNoStore();
当我注释掉最后两行代码时,字体突然开始在 IE 上正常工作。所以我猜答案是:如果没有缓存,IE 无法加载字体。不过,我不知道为什么只有在刷新/导航回来时才会出现问题。
编辑 - 替代解决方案
而不是评论最后两行
// do not use any of the following two - they break CSS fonts on IE HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.Cache.SetNoStore();
将SetAllowResponseInBrowserHistory
改为true
:
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);
据我所知,这应该仍然允许无缓存,除了向后和向前导航。 MSDN - SetAllowResponseInBrowserHistory Method
【讨论】:
【参考方案5】:JustAMartin 的answer 让我们找到了不同的解决方案:
而不是评论最后两行
// do not use any of the following two - they break CSS fonts on IE HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache); HttpContext.Current.Response.Cache.SetNoStore();
我们添加了以下行:
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);
据我所知,这应该仍然允许无缓存,除了向后和向前导航。 MSDN - SetAllowResponseInBrowserHistory Method
【讨论】:
【参考方案6】:删除全局响应 NoCache 和 NoStore 设置将修复字体,但如果您需要这些设置,那么显然这不是答案。
我的理解是,仅将缓存设置为过期不会一直阻止缓存页面的显示;它会强制检查服务器,但如果页面未修改(304 响应)可能(通常?)仍显示缓存版本。
(实际上,现在阅读本文时,我突然想到将客户端缓存设置为立即过期并结合 SetNoServerCaching 可能会强制客户端页面始终更新?似乎它可能会对性能产生影响。)
我发现在 ASP.NET MVC 中使用控制器上的 OutputCacheAttribute 属性来禁用缓存不会破坏 IE 字体。
[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
public class FooController : Controller
...
我意识到 NoStore 与 SetCacheability(HttpCacheability.NoCache) 不同,但它似乎适用于此目的。
您可以创建一个具有要继承的属性的基本控制器,以使代码更简洁。
【讨论】:
【参考方案7】:我也遇到过同样的问题。
如果 .eot 文件的头部包含 Cache-Control: no-cache 值,IE9 不能正确加载字体. 开发工具显示 Result - 200,但列 Received 显示 400B,同时 Content-长度为70Kb。 我使用了以下值 Cache-Control: max-age=0 来解决问题。
【讨论】:
我使用了 Fiddler 工具的自动回复功能。 如果我能给你更多+1,我会的。这正是我们看到的问题 - ie9 在获取字体标题后断开连接。在字体文件夹中添加了一个缓存指令,它现在对我们有用。【参考方案8】:确保这不是路径问题,即您的 CSS 文件与字体所在的位置相关。在您的情况下,您需要将 CSS 文件与字体文件放在同一文件夹中。
【讨论】:
好点。我编辑了我的帖子以显示 IE 如何加载 CSS 文件,它似乎总是来自同一个 /Contents 文件夹。以上是关于在 IE CSS font-face 仅在通过内部链接导航时有效的主要内容,如果未能解决你的问题,请参考以下文章
在 IE 中使用 @font-face 显示未设置样式的内容
在 CSS 中加载 @font-face 时如何删除浏览器中的默认字体? “FOUT”