@font-face EOT 未通过 HTTPS 加载

Posted

技术标签:

【中文标题】@font-face EOT 未通过 HTTPS 加载【英文标题】:@font-face EOT not loading over HTTPS 【发布时间】:2011-12-06 13:58:42 【问题描述】:

总结

我在 IE 7、8、9 中通过 HTTPS 使用 @font-face 时遇到了问题 - 它根本没有加载。包含的 html 页面是否托管在 HTTPS 上并不重要,当我尝试通过 HTTP 加载 EOT 字体时它可以工作,而 HTTPS 则不能。有没有人见过这种行为?

托管字体的服务器正在发送正确的 content-type="application/vnd.ms-fontobject"

我尝试了多种字体,所以它不是特定于字体的。

字体是在Font Squirrel生成的

CSS 语法

@font-face 
font-family: 'GothamCondensedBold';
src:url('path/to/fontgothmbcd-webfont.eot');
src:url('path/to/fontgothmbcd-webfont.eot?#iefix') format('embedded-opentype'),
    url('path/to/fontgothmbcd-webfont.woff') format('woff'),
    url('path/to/fontgothmbcd-webfont.ttf') format('truetype'),
    url('path/to/fontgothmbcd-webfont.svg#GothamCondensedBold') format('svg');
font-weight: normal;
font-style: normal;

示例页面

http://gregnettles.net/dev/font-face-test.html

【问题讨论】:

这很奇怪 (IE9).. 将您的 HTML 复制到 jsbin.com,点击“保存”,点击生成的链接。两种字体都可以工作......直到你点击刷新。 更新 LDG 指出(如下)问题可能是 SSL 证书与源域不匹配。这可以解释为什么 HTTP 请求有效但 HTTPS 很热。我会对此进行调查,然后将调查结果发回。 更新 无赖。原来 SSL 证书不是问题。虽然,在我的测试页面上,SSL 证书不匹配,但对于我试图让它工作的实际站点,情况并非如此,其域在 SSL 证书上。 您找到解决方案了吗?我也遇到了同样的问题。 我在 IE8 中遇到了同样的问题 - font-face over http 有效,https 无效,并且仅在第一页加载时失败,之后字体按预期显示(请参阅 ***.com/questions/7034068/…) .我安装了 Fiddler 并检查了流量。看起来 EOT 文件很好地通过了网络, Content-Type: application/vnd.ms-fontobject 。会不会只是一个 IE8 渲染错误,而我们已经陷入困境?伙计,我希望不是这样:/ 【参考方案1】:

我遇到了 HTTPS 的这个问题,但不是 HTTP。出于某种原因,IE 会继续使用不同的字体选项,而忽略 200 OK 的响应。

就我而言,问题在于字体的 HTTP 标头 Cache-Control: no-cache。虽然这适用于 HTTP,但通过 HTTPS 会导致 Internet Explorer 忽略下载的字体。

我最好的猜测是它是这种行为的一种变体:

KB 815313 - Prevent caching when you download active documents over SSL (archive)

因此,如果您在 Developer Tools 网络视图中看到 IE 可以通过每种字体工作,则可能值得检查您是否有 Cache-Control 标头并将其删除。

【讨论】:

使用 Apache,我添加了SetEnvIfNoCase Request_URI \.eot$ FONT,如果存在FONT 环境变量(Header 指令中的env=!FONT),则不要设置 Cache-Control 标头。 这刚刚解决了我使用 IE8 / SSL / IIS 8.0 的问题 - 谢谢。 是的!我们追逐了很多其他的红鲱鱼,这也是我们的问题。谢谢! 就我而言,我还需要删除Pragma: no-cache 这是一个错误报告:connect.microsoft.com/IE/feedbackdetail/view/992569/…【参考方案2】:

我知道这是一个旧线程,但我不得不权衡一下。我们在所有版本的 Internet Explorer (7-11) 中都遇到了相同的问题,即 EOT 和 WOFF 字体无法通过 HTTPS 加载。经过数小时的反复试验并将我们的标头与其他工作站点进行比较后,我们发现是 vary 标头搞砸了。取消设置这些文件类型的标头立即解决了我们的问题。

<FilesMatch "\.(woff)$">
    Header unset Vary
</FilesMatch>

<FilesMatch "\.(eot)$">
    Header unset Vary
</FilesMatch>

阅读奖励

埃里克·劳伦斯:Vary with Care (archive) IE 博客:Caching Improvements in Internet Explorer 9 (archive)

【讨论】:

我必须将上述代码行放在我的应用程序中的什么位置,因为我遇到了与您之前遇到的相同的问题。 如果您的服务器是 Apache,它将进入 .htaccess 文件。如果您的服务器是 nginx/IIS/其他任何东西,您需要转换这些规则。我建议提出另一个问题,提供更具体的细节并参考这个线程。 我知道这是在 XAMPP 的 Apache 文件夹中的某个 conf 文件中的某个位置,但是在哪里?想解释一下在哪里? 您应该能够使用这些指令在您的 Web 目录的根目录中创建一个名为 .htaccess 的常规文本文件(注意前面的句点/句号)。 过去工作过一次(我没有把它放在我的虚拟主机根目录的 htaccess 文件中,而是放在 apache/xampp conf 文件的某个位置,现在确实做了 .htaccess 的事情,但什么也没做完全发生了。仍在查看浏览器的相同控制台输出。【参考方案3】:

这通常是由于在下载 .woff 或 .eot 文件时遵循响应标头而发生的。

Cache-Control = no-cache, no-store, max-age=0, must-revalidate Pragma = 无缓存

在我的情况下,我使用的是 spring-boot 并删除这些标题,我必须执行以下操作。这也解决了这个问题。

public class SecurityConfig extends WebSecurityConfigurerAdapter  
@Override
public void configure(HttpSecurity http) throws Exception 
   http.headers().defaultsDisabled()
        .addHeaderWriter(new StaticHeadersWriter("Cache-Control"," no-cache,max-age=0, must-revalidate"))
        .addHeaderWriter(new StaticHeadersWriter("Expires","0"));
 

【讨论】:

如果你想保留其余的默认标题,你可以写.headers().cacheControl().disable()而不是.headers().defaultsDisabled()【参考方案4】:

这是我的解决方法:

使用 IIS 的 URL 重写插件为所有 EOT 文件设置 Cache-Control 标头:

<system.webServer>
....
<rewrite>
  <outboundRules>
    <rule name="Fix IE9 missing font icons">
      <match serverVariable="RESPONSE_Cache_Control" pattern=".*" />
      <conditions>
          <add input="REQUEST_URI" pattern="\.eot.*" />
      </conditions>
      <action type="Rewrite" value="private, max-age=36000" />
    </rule>
  </outboundRules>
</rewrite>
</system.webServer>

【讨论】:

使用 IE、SSL (HTTPS),响应头如下:Cache-Control: no-store, no-cache, must-revalidate, max-age=0。这解决了我的问题。 @user3335999 对于某些文件,使用缓存有利于提高性能。如果您的文件是 EOT 文件,那么最好不要完全禁用缓存。【参考方案5】:

没有缓存头,我注意到 Windows Vista 上的 IE9 客户端仍然不加载字体(即使在我的新开发机器上,IE9 仿真模式下的 IE11 也会这样做)。

我能够在客户端计算机上通过 Internet Explorer 解决该问题,方法是:

Internet 选项 高级 安全性

并取消选中“不将加密页面保存到磁盘”选项。

阅读奖励

埃里克·劳伦斯:Avoid “Do not save encrypted pages to disk” (archive)

HTH

【讨论】:

谢谢你,这对我有帮助 :) 这是msdn blog 说没有咨询标题。【参考方案6】:

我似乎记得某些版本的 IE 出于某种原因不能使用托管在站点域之外的 @fontface 字体(如果页面位于 http://a.domain.tld/page.html - 字体也必须位于 http://a.domain.tld/ 中)。将 EOT 文件放在您的域中,然后再试一次。

IE9 blocks download of cross-origin web font

【讨论】:

如果您查看我的示例页面,您会看到该页面托管在与字体不同的域上,并且它适用于 HTTP,但不适用于 HTTPS。将 EOT 与页面放在同一个域中不是一种选择,因为它是由 CDN 托管的。 我做到了,因此我建议将其托管在您的域上。如果您在 *nix 下运行,我建议您然后尝试reverse proxy,以诱使浏览器认为内容在您的域中。 对,但是它使用非HTTPS协议跨域工作,这让我相信它与HTTPS有关,而不是跨域。反向代理解决方案很智能,但不幸的是,我们无法访问托管文件的服务器配置。 同样的问题,即使我们所有的字体都托管在使用它们的页面的同一服务器(和域)上。【参考方案7】:

Apache/2.2.15 的工作解决方案是添加 .htaccess

<FilesMatch "\.(woff)$">
    Header unset Cache-control
</FilesMatch>

<FilesMatch "\.(eot)$">
    Header unset Cache-control
</FilesMatch>

【讨论】:

【参考方案8】:

此问题现已通过将以下条目添加到 apache 服务器中的 httpd.conf 或 .htaccess 得到解决。

为了让它工作,我们已经从使用 FilesMatch 更改为 LocationMatch,现在标题设置完美。

要为字体文件设置正确的 mime 类型,请将以下行添加到配置中:

 AddType application/vnd.ms-fontobject .eot
 AddType font/truetype .ttf
 AddType font/opentype .otf
 AddType font/opentype .woff
 AddType image/svg+xml .svg .svgz

为了更新字体文件头,这个修复完美地在 IE 浏览器中呈现字体图标。

<LocationMatch "\.(eot|otf|woff|ttf)$">
   Header unset Cache-Control
   Header unset no-store
</LocationMatch >

【讨论】:

【参考方案9】:

您是否尝试过通过 https 直接下载 EOT 文件? SSL 证书似乎有问题(不匹配),这很可能是您的问题。

您还应该确保为这些文件设置了跨域策略,因此虽然它可能不是问题的一个因素,但它可能会导致某些浏览器出现问题。

【讨论】:

好点,我没想到SSL证书不匹配的问题!我会为此做一些研究。是的,服务器正在发送带有字体的 content-access-allow-origin=* 标头,所以这应该很好。在添加之前,我们遇到了 Firefox 的问题。 好主意,但我认为这不是问题 - 我在最初的问题上添加了一条评论来解释。【参考方案10】:

这听起来像是您的 CDN 有问题。您可以通过更改您的主机文件以使您的 SSL 域指向您的非 SSL 流量所提供的任何 IP 来验证这一点。如果字体呈现,您需要调用您的 CDN 并弄清楚他们的服务器对字体文件做了什么。

【讨论】:

【参考方案11】:

我遇到了类似的问题,但罪魁祸首是 Vary 标头。在我的设置中,我使用 Ruby on Rails 和 rack-cors gem。它为字体文件提供了Vary: Origin 的标题。要解决此问题,您可以将标头设置为 Accept-Encoding 您设置中间件的位置:

config.middleware.insert_before 0, "Rack::Cors", :debug => true, :logger => (->  Rails.logger ) do
  allow do
    origins '*'

    resource '/cors',
      :headers => :any,
      :methods => [:post],
      :credentials => true,
      :max_age => 0

    resource '*',
      :headers => :any,
      :methods => [:get, :post, :delete, :put, :options, :head],
      :max_age => 0,
      vary: ['Accept-Encoding'] # Required or IE11 fonts will break
  end
end

【讨论】:

【参考方案12】:

尝试使用 https://... 的完整网址。由于 https 会因为文件放大和不可压缩而变慢,因此有一些技巧可以提供混合的 http/https 内容,而不会收到“不安全内容”警告。您可能会搜索它们。从来不需要使用这些技巧。

【讨论】:

感谢 Joop,如果您查看我的示例页面,您会看到我尝试使用带有“https”的完整 URL 无济于事。关于 SSL 速度较慢的好点,但问题不在于 HTTPS 速度或混合内容,但无论如何感谢您的写作。【参考方案13】:

好的,据我所知,这是一个 IE8 错误。我创建了一个至少适用于 Apache 的解决方法 - 使用 mod_rewrite 强制 HTTP 请求以“.eot”或“.eot”结尾?并对所有其他请求强制使用 HTTPS。在您的 .htaccess 文件中,执行:

<IfModule mod_rewrite.c>
  RewriteEngine on

  # if HTTPS request, force to HTTP if file ends in '.eot' or '.eot?'
  RewriteCond %SERVER_PORT 443
  RewriteCond %REQUEST_URI ^.*\.eot\??$
  RewriteRule (.*) http://%HTTP_HOST%REQUEST_URI [R=301,L]

  # if HTTP request, force to HTTPS if file does NOT end in '.eot' or '.eot?'
  RewriteCond %SERVER_PORT 80
  RewriteCond %REQUEST_URI !.*\.eot\??$
  RewriteRule (.*) https://%HTTP_HOST%REQUEST_URI [R=301,L]

</IfModule>

不是很漂亮,而且我确信它会增加一些服务器开销,每个请求都运行字符串比较,但它解决了问题:)

【讨论】:

有趣的解决方案 - 很高兴它对你有用。就我而言,我没有能力修改 mod_rewrite 规则。最终只是在 IE 中使用了不同的字体 =( 谢谢格雷格。是的,绝对需要访问 mod_rewrite :/ 对于 HTTPS 页面,浏览器会发出警告,指出您的页面包含不安全的资源。例如,您将在 Chrome 中获得黄色锁 support.google.com/chrome/answer/95617?hl=en【参考方案14】:

您好,我刚刚遇到了同样的问题,我已经找到了解决方法,希望这可以帮助其他人。

如评论所述,这是 IE https://communities.bmc.com/thread/88899 处查看有关该问题的一些信息。基本上问题是在 IE 中通过 https 下载文件并设置了 Cache: no-cache 标头,尝试删除缓存标头以查看这是否是您的问题。

这个答案也可能对IE : Unable to download * from *. Unable to open this Internet site. The requested site is either unavailable or cannot be found有帮助

【讨论】:

【参考方案15】:

想分享我的情况和解决方案,希望对下一个人有所帮助。

我的字体是通过 Amazon CloudFront 通过 HTTPS 交付的,该服务器被配置为提供来自我们的应用程序的静态资产,该应用程序位于 Elastic Load Balancer 后面强>.

字体具有以下标题:

Access-Control-Allow-Origin: *
Cache-Control: public, max-age=100000
Cache-Control: no-cache="set-cookie"

根据我在互联网上可以找到的其他答案和内容,我预计这会起作用,因为它设置了 max-age 并具有正确的 CORS 配置。但是,IE9 仍然不会渲染字体。

问题原来是 Cache-Control: no-cache="set-cookie" 标头,这让我感到惊讶,因为这只是说不缓存 Set-Cookie 标头(除非我弄错了)。

我花了一段时间才弄清楚该标题的来源。我们的 ELB 正在添加此标头,因为我们通过 cookie 使用粘性会话,我猜负载均衡器配置为在以这种方式设置时使用此 Cache-Control 标头。

因此关闭粘性会话会删除标题,并导致字体呈现。我们能够为 HTTP 请求关闭粘性会话,并为 HTTPS 请求保留它们,这很好,因为我们对任何非静态资产强制使用 SSL,但无论是否使用 SSL,我们都很乐意将静态资产提供给 CloudFront。

希望其他人能发现此信息有用。

【讨论】:

【参考方案16】:

很老的问题,但我认为没有人回答正确。问题是字体是从另一个文件加载的,对我来说这似乎是 Access-Controll-Allow-Origin 的情况。

它的工作原理非常简单,在您的 virtualhosts 文件或 .htaccess 中添加以下内容:

<ifModule mod_headers.c>
    Header set Access-Control-Allow-Origin: *
</ifModule>

然后重启apache

【讨论】:

【参考方案17】:

通过 HTTPS 使用 IE 11 的 Web 字体可能会出现问题,而使用 HTTP 可以正常工作。

只有特定版本的 IE 11 受影响,例如

版本 11.0.9600.19035,更新版本 11.0.65 版本 11.0.9600.17728,更新版本 11.0.18。

在 Win 7 上都是 IE。我在 Win 8 或 Win 10 上没有看到问题。

即使 Google 声明支持 Microsoft Internet Explorer 6+ 版,它们的字体也会受到与上述相同的影响。

目前我知道没有解决方法,甚至没有通过 HTML/CSS/javascript 检测受影响版本的方法。

【讨论】:

【参考方案18】:

我能够解决 https 页面上 IE 中字体不工作的问题。我发现的唯一可行的选择是通过 css 下载 base64 中的字体

@font-face 
    font-family: 'your font name';
    src: url('data:application/font-woff2;charset=utf-8;base64,...base64FontWoff2...') format('woff2'),url('data:application/font-woff;charset=utf-8;base64,...base64FontWoff...') format('woff');
    font-weight: normal;
    font-style: normal;
    font-display: swap;

在这个网站上你可以在这里准备一个 css 文件 - https://transfonter.org/

【讨论】:

以上是关于@font-face EOT 未通过 HTTPS 加载的主要内容,如果未能解决你的问题,请参考以下文章

IE8 上的 @font-face datauri 是不是支持 .eot 字体?

在 IE 中使用 @font-face 显示未设置样式的内容

@font-face 连字缺失

新的防弹@Font-Face语法

@font-face 的离线字体转换器

声明font-face时使用多个字体文件类型源是否有好处?