31

我们的网页设计师创建了一个具有以下字体的 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 在刷新/返回操作时加载正确的字体?

4

8 回答 8

23

我找到了一个解决方案,但我看不到它起作用的原因(嗯,只有一个原因 - 它是 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 方法

于 2012-11-16T21:39:47.150 回答
16

我遇到了同样的问题。

如果.eot文件的标头包含Cache-Control: no-cache值,IE9将无法正确加载字体。开发工具显示Result - 200,但Received列显示 400B,同时Content-Length为 70Kb。我使用了以下值Cache-Control: max-age=0来解决问题。

于 2013-08-12T21:33:16.803 回答
6

我只是有同样的错误,对于那些想要一个纯粹的解决方案(非精确技术相关)的人:你需要确保你发送的字体标题不是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"或删除。
于 2016-05-17T07:44:42.493 回答
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 命令进行字体编码。

于 2017-05-03T15:07:31.260 回答
3

JustAMartin回答让我们找到了不同的解决方案:

而不是评论最后两行

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

于 2015-09-18T10:23:21.477 回答
2

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

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

(实际上,现在阅读本文时,我想到将客户端缓存设置为立即过期并结合 SetNoServerCaching 可能会强制客户端页面始终更新?似乎它可能会对性能产生影响。)

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

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

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

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

于 2015-01-07T23:30:14.593 回答
1

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

于 2012-11-16T10:56:36.740 回答
1

不要将 Vary Request Header 设置为 https

没有字体加载

Vary:Accept-Encoding,https

作品

Vary:Accept-Encoding

设置缓存头对于避免延迟字体加载是必要的。

于 2017-08-30T14:17:44.277 回答