使用Node下载.ttf文件

时间:2014-10-21 12:54:02

标签: javascript css node.js http font-face

我正在尝试使用Node下载像this one这样的 .ttf 文件。

我正在使用mikeal/request来处理HTTP请求。 实际函数看起来像这样:

request.get(url, function(err, res, body) {
  if(err) throw err;
  fs.writeFileSync(path, body);
});

快速浏览一下后,它表现得与预期完全一样;一切都在正确的地方结束,看起来或多或少是正确的。

但是,当我尝试使用以下@font-face代码段将字体加载到浏览器中时,应用了规则,但字体不是。没有错误,没有任何错误加载或被覆盖。

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: local('Open Sans'), local('OpenSans'), url(cJZKeOuBrn4kERxqtaUH3aCWcynf_cDxXwCLxiixG1c.ttf) format('truetype');
}

对于初步检查,我尝试用KFontView打开它,但遇到“无法读取字体”错误。

我通过wgeting该文件的新副本并执行相同的操作来验证此错误。它加载到预览中。

这使我的记忆慢慢关于可以传递给writeFile的可选参数,所以我检查了wget版本和节点版本的编码。

$ enca wget.ttf -L none
> Unrecognized Encoding
$ enca node.ttf -L none
> Universal transformation format 8 bits; UTF-8
>  Mixed line terminators
>  Surrounded by/intermixed with non-text data

所以,相当明显。 wget将其保存为二进制文件,而节点将其作为UTF-8写入文件。 Quicky通过file

确认
$ file -i wget.ttf
> wget.ttf: application/x-font-ttf; charset=binary

快速扫描Node文档,结果我可以做到这一点

fs.writeFileSync(path, body, 'binary');

一切看起来都不错,节点版本现在显示为正确的编码。但是,在浏览器中仍然存在完全相同的问题。

确保我的Chrome版本支持.ttf font-faces(版本37.0.2062.94(64位)。确实如此。)

据我所知,该文件现在是相同的。差异特别无益。

$ diff wget.ttf node.ttf
> Binary files wget.ttf and node.ttf differ.

使用带有二进制文件的diff可能有更合理的方法。害怕,我对此不太了解。我决定去寻找原始的手工差异。

Hex View

我启动了vim,将两个文件都放在屏幕上并将它们敲入十六进制模式以查看。 Apple,Microsoft和Adobe似乎对TTF文件都有不同的规范,我不确定这些规范是什么,但我猜第一行字节是通用标头的一部分。

在第一行字节之后,文件的其余部分是不同的。

这里到底发生了什么? Node如何以不同的文件结束wget?

  • 是否有任何实用程序传递会影响所服务文件的任何奇怪标头?
  • 这对我使用writeFile的方式有问题吗?

我希望我错过了一些明显的东西。否则,欢迎任何建议。

1 个答案:

答案 0 :(得分:2)

您需要通过将encoding设置为null来指定您想要二进制编码。

request.get({
  url: url,
  encoding: null,
}, function (err, res, body) {

否则,它将默认为UTF-8编码。文档:https://github.com/mikeal/request

但实际上,为了提高效率,你应该让它流式传输到一个文件。

request('http://example.com/font.ttf').pipe(fs.createWriteStream('font.ttf'));