在IE CSS上,font-face仅在浏览内部链接时有效

时间:2012-11-16 10:49:53

标签: css internet-explorer https font-face

我们的webdesigner使用以下font-face创建了一个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上,只有当我使用内部网页链接导航页面时才能正确呈现字体。如果我点击“刷新”或“后退”按钮,则字体将被默认字体(Times New Roman)替换。

目前网站使用的是HTTPS,但在使用HTTP时遇到了同样的问题。

当我使用内部网站链接导航时,在IE Developer工具的网络选项卡中(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):在浏览后退/刷新时显示不正确的后备字体。

如何让IE在刷新/返回操作上加载正确的字体?

8 个答案:

答案 0 :(得分:22)

我找到了一个解决方案,但我看不出它的工作原因(好吧,只有一个原因 - 它是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

答案 1 :(得分:15)

我遇到了同样的问题。

如果 .eot 文件的标头包含 Cache-Control:no-cache 值, IE9 不能正确加载字体。 开发工具显示 结果 - 200,但 收到 列显示400B,同时内容 - 长度为70Kb。 我使用了以下值 Cache-Control:max-age = 0 来解决问题。

答案 2 :(得分:6)

我遇到了同样的错误,对于那些想要拥有纯解决方案的人(非精确技术相关):您需要确保您发送的字体标题不是"cache-control: no-cache" 。除了以前写的内容之外,实际上有两个标题可以做到:

"pragma: no-cache"

"cache-control" to "max-age=0"

两者都说浏览器相同,第一个是HTTP1.1的一部分,第二个是旧的(HTTP1.0)。

现在,解决方案:

  • 如果你真的想要提供字体(和其他文件?)而没有 客户端缓存,设置"pragma: cache";您可以删除编译指示标题,它已过时(或将其设置为no-cache)。
  • 如果您确实想要缓存:删除"cache-control: max-age=3600"值,并设置正确的max-age(例如"pragma: cache" - 一小时缓存)。 Pragma可以设置为couldn't find or load main class org.codehaus.groovy.grails.cli.support.GrailsStarter 或完全删除。

答案 3 :(得分:4)

我找到了解决此问题的替代解决方案。

我已将字体直接嵌入样式表中,而不是作为单独的字体文件加载。这适用于所有浏览器,包括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命令进行字体编码。

答案 4 :(得分:3)

JustAMartinanswer让我们找到了另一种解决方案:

而不是评论最后两行

    // 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

答案 5 :(得分:2)

删除全局响应NoCache和NoStore设置将修复字体,但如果您需要这些设置,那么显然不是答案。

我的理解是,只将缓存设置为过期将不会始终阻止缓存页面的显示;它强制检查服务器,但如果页面未被修改(304响应)可能(通常?)仍然显示缓存版本。

(实际上现在读到这一点,我发现将客户端缓存设置为与SetNoServerCaching一起立即过期可能会强制客户端页面始终更新?看起来它可能会影响性能。)

我发现在ASP.NET MVC中使用控制器上的OutputCacheAttribute属性来禁用缓存不会破坏IE字体。

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
public class FooController : Controller
{
    ...
}    

我意识到NoStore与SetCacheability(HttpCacheability.NoCache)不同,但它似乎可以用于此目的。

您可以使用要继承的属性创建一个基本控制器,以使代码更清晰。

答案 6 :(得分:1)

确保它不是路径问题,即您的CSS文件与字体的位置有关。在您的情况下,您需要与您的字体文件在同一文件夹中的CSS文件。

答案 7 :(得分:1)

不要将Vary Request Header设置为https

无字体加载

Vary:Accept-Encoding,https

<强>作品

Vary:Accept-Encoding

avoid delayed font loading需要设置缓存标头。