通过nodejs下载谷歌字体,实时转换为base64用于css datauri

时间:2018-03-02 18:44:45

标签: node.js svg server download webfonts

最终目标是生成并提供一个svg,它将所有外部元素内联为datauris,以便生成的svg可以在html5画布中用于动态生成图像。

我已经设法在输出svg中的服务器上动态下载和嵌入图像,但svgs还包括用户可以随机选择的谷歌字体,因此还需要从中下载指定的字体文件谷歌,将其转换为base64,并将其作为@ font-face中的数据库放入svg的css中。

到目前为止,字体只是拒绝工作。

如果我使用在线服务转换完全相同的字体文件并粘贴代替我转换后的字体数据,那么它可以工作,所以我下载字体的方式或者我如何转换都有问题它到base64。

所有下载和转换都在服务器上进行,因此我可以为“一体化”svg提供服务。我正在使用Firebase的Cloud Functions,它使用nodejs。

我已经知道了,所以我可以下载谷歌字体导入文件(例如:https://fonts.googleapis.com/css?family=Comfortaa),它返回一个css @ font-face导入字符串,例如:

@font-face {
  font-family: 'Comfortaa';
  font-style: normal;
  font-weight: 400;
  src: local('Comfortaa Regular'), local('Comfortaa-Regular'), url(https://fonts.gstatic.com/s/comfortaa/v12/1Ptsg8LJRfWJmhDAuUs4QIFqL_KWxWMT.woff2) format('woff2');
}

然后我提取实际字体文件的url(即:https://fonts.gstatic.com/s/comfortaa/v12/1Ptsg8LJRfWJmhDAuUs4QIFqL_KWxWMT.woff2)并使用nodejs'https下载字体并将其作为承诺返回。

function getFontToImport( file ) {
    return new Promise( ( resolve , reject ) => {
        https.get( file , ( res ) => {
            const { statusCode } = res;
            const contentType = res.headers['content-type'];
            let error;
            if (statusCode !== 200) {
                error = new Error('Request Failed.\n' + `Status Code: ${statusCode}`);
            }
            if ( error ) {
                // consume response data to free up memory
                res.resume();
                resolve( error ) ;
            }

            //res.setEncoding('utf8');
            let rawData = '';
            res.on('data', (chunk) => { rawData += chunk; });
            res.on('end', () => {
                try {
                    resolve( rawData ) ;
                } catch ( e ) {
                  console.log( 'Could not log the file' ) ;
                  console.error(e.message);
                  resolve( e.message ) ;
                }
            });
        }).on( 'error' , (e) => {
          console.error( 'Got error:' + e.message ) ;
          resolve( e.message ) ;    
        });    
    }) ;    
}

然后我使用:

将该数据转换为base64

const base_64 = new Buffer(rawData).toString('base64');

我将它注入我创建的@ font-face css中的svg代码中,但字体无法显示。如果我使用在线转换器将相同的字体转换为base64,并在@ font-face中粘贴代替我的base64数据库,则文本显示正常,因此问题与我如何下载和/或转换有关字体。

当我将通过我的nodejs函数下载的字体版本与通过浏览器下载的同一文件进行比较时,它们看起来完全不同。

以下是使用我正在处理的函数的页面链接,其中包含一些不同的输出:https://us-central1-project-7161459789373699890.cloudfunctions.net/font64?font=Comfortaa

我认为问题特别在于我如何下载字体。我真的不知道节点所以我只是复制了一个例子,它对图像效果很好。它不适用于字体,所以我按照建议取出了编码,但仍然没有运气。

如果有人可以提供任何建议或提供有关通过节点加载字体数据与使用浏览器直接访问字体链接下载的字体数据之间差异的说明,我将非常感谢。

1 个答案:

答案 0 :(得分:1)

必须将编码设置为'binary'。

默认情况下,它设置为utf8,因此删除编码设置误导我认为数据将以默认编码方式通过。将编码设置为二进制允许数据以正确的格式通过,然后允许它正确地转换为base64,这使其在用作数据库时能够正确显示。