如何在我自己的服务器上托管谷歌网络字体?

时间:2012-01-23 02:52:56

标签: fonts google-font-api

我需要在Intranet应用程序上使用一些谷歌字体。客户可能有也可能没有互联网连接。阅读许可条款,似乎是合法允许的。

19 个答案:

答案 0 :(得分:202)

请记住,我的答案已经老了很多。

下面还有其他技术更为复杂的答案,例如:

所以不要让这个是目前接受的答案的事实给你的印象是这仍然是最好的。


您现在还可以通过github在google/font存储库下载google的整个字体集。他们还提供~360MB zip snapshot of their fonts


首先将字体选择下载为压缩包,为您提供一堆真实字体。将它们复制到公共场所,您可以从css链接到的地方。

在google webfont下载页面上,您会找到类似的包含链接:

http://fonts.googleapis.com/css?family=Cantarell:400,700,400italic,700italic|Candal

它通过一系列@font-face定义链接到定义字体的CSS。

在浏览器中打开它,将它们复制并粘贴到您自己的CSS中,并修改网址以包含正确的字体文件和格式类型。

所以这个:

@font-face {
  font-family: 'Cantarell';
  font-style: normal;
  font-weight: 700;
  src: local('Cantarell Bold'), local('Cantarell-Bold'), url(http://themes.googleusercontent.com/static/fonts/cantarell/v3/Yir4ZDsCn4g1kWopdg-ehHhCUOGz7vYGh680lGh-uXM.woff) format('woff');
}

成为这个:

/* Your local CSS File */
@font-face {
    font-family: 'Cantarell';
    font-style: normal;
    font-weight: 700;
    src: local('Cantarell Bold'), local('Cantarell-Bold'), url(../font/Cantarell-Bold.ttf) format('truetype');
}

正如您所看到的,通过这种方式在您自己的系统上托管字体的缺点是,您将自己限制为真正的类型格式,而google webfont服务通过访问设备确定将传输哪些格式。

此外,我必须在我的目录中添加一个.htaccess文件,其中包含包含mime类型的字体,以避免在Chrome开发工具中弹出错误。

对于此解决方案,只需要真正的类型,但是当您想要包含不同的字体时,定义更多类型也不会受到影响,例如font-awesome

#.htaccess
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType application/x-font-woff .woff

答案 1 :(得分:197)

有一个工具localfont.com可以帮助您下​​载所有字体变体。它也会生成相应的CSS以供实现。 已弃用

localfont失败了。相反,作为Damir suggests,您可以使用google-webfonts-helper


答案 2 :(得分:126)

很好的解决方案是google-webfonts-helper

它允许您选择多个字体变体,这样可以节省大量时间。

答案 3 :(得分:58)

我写了一个bash script,它使用不同的用户代理在Google的服务器上获取CSS文件,将不同的字体格式下载到本地目录并写入包含它们的CSS文件。请注意,该脚本需要Bash版本4.x。

请参阅https://neverpanic.de/blog/2014/03/19/downloading-google-web-fonts-for-local-hosting/脚本(我不会在此处复制它,所以我只需要在一个地方更新它)。

修改:已移至https://github.com/neverpanic/google-font-download

答案 4 :(得分:12)

CSS文件的内容(来自包含URL)取决于我从哪个浏览器查看它。例如,使用Chrome浏览http://fonts.googleapis.com/css?family=Open+Sans时,该文件仅包含WOFF链接。使用Internet Explorer(下面),它包括EOT和WOFF。我将所有链接粘贴到浏览器中以下载它们。

@font-face {
  font-family: 'Open Sans';
  font-style: normal;
  font-weight: 400;
  src: url(http://themes.googleusercontent.com/static/fonts/opensans/v6/cJZKeOuBrn4kERxqtaUH3fY6323mHUZFJMgTvxaG2iE.eot);
  src: local('Open Sans'), local('OpenSans'), url(http://themes.googleusercontent.com/static/fonts/opensans/v6/cJZKeOuBrn4kERxqtaUH3fY6323mHUZFJMgTvxaG2iE.eot) format('embedded-opentype'), url(http://themes.googleusercontent.com/static/fonts/opensans/v6/cJZKeOuBrn4kERxqtaUH3T8E0i7KZn-EPnyo3HZu7kw.woff) format('woff');
}

当您托管自己的网络字体时,需要correctly link to each font type,处理旧版浏览器错误等。当您使用Google网络字体(由Google托管)时,Google会自动链接到正确的字体类型浏览器。

答案 5 :(得分:6)

只要您遵守字体许可证的条款(通常是OFL),法律允许。

您需要一组网络字体格式,Font Squirrel Webfont Generator可以生成这些格式。

但OFL要求修改字体时重命名字体,使用生成器意味着修改字体。

答案 6 :(得分:2)

我有一个用PHP编写的类似于@neverpanic的脚本,它自动从Google下载CSS和字体(暗示和未暗示)。然后,它会根据用户代理从您自己的服务器提供正确的CSS和字体。它保留了自己的缓存,因此用户代理的字体和CSS只能下载一次。

它处于早熟阶段,但可以在此处找到:DaAwesomeP / php-offline-fonts

答案 7 :(得分:1)

我的解决方案是从谷歌网络字体下载TTF文件,然后使用onlinefontconverter.com

答案 8 :(得分:1)

您可以遵循使用PHP开发的脚本。 您可以在其中使用脚本下载任何Google字体。 它将下载字体并创建CSS文件并存档为zip。
您可以从GitHub https://github.com/sourav101/google-fonts-downloader

下载源代码。
$obj = new GoogleFontsDownloader;

if(isset($_GET['url']) && !empty($_GET['url']))
{
    $obj->generate($_GET['url']);
}

if(isset($_GET['download']) && !empty($_GET['download']) && $_GET['download']=='true')
{
    $obj->download();
}

/**
* GoogleFontsDownloader
* Easy way to download any google fonts.
* @author     Shohrab Hossain
* @version    1.0.0 
*/
class GoogleFontsDownloader
{
    private $url      = '';
    private $dir      = 'dist/';
    private $fontsDir = 'fonts/';
    private $cssDir   = 'css/';
    private $fileName = 'fonts.css';
    private $content  = '';
    private $errors   = '';
    private $success  = '';
    public  $is_downloadable  = false;

    public function __construct()
    {
        ini_set('allow_url_fopen', 'on');
        ini_set('allow_url_include', 'on');
    }

    public function generate($url = null)
    {
        if (filter_var($url, FILTER_VALIDATE_URL) === FALSE) 
        {
            $this->errors .= "<li><strong>Invalid url!</strong> $url</li>";
        }
        else
        {
            $this->url = $url;
            // delete previous files
            $this->_destroy();
            // write font.css
            $this->_css();
            // write fonts
            $this->_fonts();
            // archive files
            $this->_archive();
        }  
        // show all messages
        $this->_message();
    }

    public function download()
    { 
        // Download the created zip file
        $zipFileName = trim($this->dir, '/').'.zip';
        if (file_exists($zipFileName))
        {
            header("Content-type: application/zip");
            header("Content-Disposition: attachment; filename = $zipFileName");
            header("Pragma: no-cache");
            header("Expires: 0");
            readfile("$zipFileName");

            // delete file 
            unlink($zipFileName);
            array_map('unlink', glob("$this->dir/*.*"));
            rmdir($this->dir);

        } 
    }   

    private function _archive()
    {
        if (is_dir($this->dir))
        {
            $zipFileName = trim($this->dir, '/').'.zip';
            $zip = new \ZipArchive(); 
            if ($zip->open($zipFileName, ZipArchive::CREATE) === TRUE) 
            {
                $zip->addGlob($this->dir. "*.*");
                $zip->addGlob($this->dir. "*/*.*");
                if ($zip->status == ZIPARCHIVE::ER_OK)
                {
                    $this->success .= '<li>Zip create successful!</li>';
                    $this->is_downloadable = true;
                }
                else 
                {
                    $this->errors .= '<li>Failed to create to zip</li>';
                } 
            } 
            else 
            {
                $this->errors .= '<li>ZipArchive not found!</li>';
            }  
            $zip->close(); 
        }
        else
        {
            $this->errors .= "<li><strong>File</strong> not exists!</li>";
        } 
    }   

    private function _css()
    {  
        $filePath = $this->dir.$this->cssDir.$this->fileName;
        $content  = $this->_request($this->url);
        if (!empty($content))
        {
            if (file_put_contents($filePath, $content))
            {
                $this->success .= "<li>$this->fileName generated successful!</li>";
                $this->content = $content; 
            }
            else
            {
                $this->errors .= '<li>Permission errro in $this->fileName! Unable to write $filePath.</li>';
            }
        }
        else
        {
            $this->errors .= '<li>Unable to create fonts.css file!</li>';
        }
    }

    private function _fonts()
    {
        if (!empty($this->content))
        {
            preg_match_all('#\bhttps?://[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))#', $this->content, $match);
            $gFontPaths = $match[0];
            if (!empty($gFontPaths) && is_array($gFontPaths) && sizeof($gFontPaths)>0)
            {
                $count = 0;
                foreach ($gFontPaths as $url) 
                {
                    $name     = basename($url);
                    $filePath = $this->dir.$this->fontsDir.$name;
                    $this->content = str_replace($url, '../'.$this->fontsDir.$name, $this->content);

                    $fontContent  = $this->_request($url);
                    if (!empty($fontContent))
                    {
                        file_put_contents($filePath, $fontContent);
                        $count++;
                        $this->success .= "<li>The font $name downloaded!</li>";
                    }
                    else
                    {
                        $this->errors .= "<li>Unable to download the font $name!</li>";
                    } 
                }

                file_put_contents($this->dir.$this->cssDir.$this->fileName, $this->content);
                $this->success .= "<li>Total $count font(s) downloaded!</li>";
            }
        }
    }

    private function _request($url)
    {
        $ch = curl_init(); 
        curl_setopt_array($ch, array(
            CURLOPT_SSL_VERIFYPEER => FALSE,
            CURLOPT_HEADER         => FALSE,
            CURLOPT_FOLLOWLOCATION => TRUE,
            CURLOPT_URL            => $url,
            CURLOPT_REFERER        => $url,
            CURLOPT_RETURNTRANSFER => TRUE,
        ));
        $result = curl_exec($ch);
        curl_close($ch);

        if (!empty($result))
        {
            return $result;
        } 
        return false;
    }

    private function _destroy()
    {
        $cssPath = $this->dir.$this->cssDir.$this->fileName;
        if (file_exists($cssPath) && is_file($cssPath))
        {
            unlink($cssPath);
        } 
        else
        {
            mkdir($this->dir.$this->cssDir, 0777, true);
        }

        $fontsPath = $this->dir.$this->fontsDir;
        if (!is_dir($fontsPath))
        {
            mkdir($fontsPath, 0777, true);
        }
        else
        {
            array_map(function($font) use($fontsPath) {
                if (file_exists($fontsPath.$font) && is_file($fontsPath.$font))
                {
                    unlink($fontsPath.$font);
                }
            }, glob($fontsPath.'*.*')); 
        }
    }

    private function _message()
    {
        if (strlen($this->errors)>0)
        {
            echo "<div class='alert alert-danger'><ul>$this->errors</ul></div>";
        }  
        if (strlen($this->success)>0)
        {
            echo "<div class='alert alert-success'><ul>$this->success</ul></div>";
        } 
    } 
}

答案 9 :(得分:1)

如果您使用的是Webpack,则可能对此项目感兴趣:https://github.com/KyleAMathews/typefaces

E.g。说你想使用Roboto字体:

npm install typeface-roboto --save

然后只需在应用程序的入口点(主js文件)中导入它:

import 'typeface-roboto'

答案 10 :(得分:1)

如果您想在自己的服务器上托管所有字体(或其中一些字体),您可以从此repo下载字体并按照您想要的方式使用它:https://github.com/praisedpk/Local-Google-Fonts

答案 11 :(得分:1)

我制作了一个很小的PHP脚本,可以从Google字体CSS导入网址获取下载链接,例如:https://fonts.googleapis.com/css?family=Roboto:400,700|Slabo+27px|Lato:400,300italic,900italic

您可以在此处使用此工具:http://nikoskip.me/gfonts.php

例如,如果您使用上述导入网址,则会收到以下信息:

enter image description here

答案 12 :(得分:1)

您实际上可以直接从Google下载所有字体格式变体,并将它们包含在您的css中,以便从您的服务器提供服务。这样,您就不必担心Google会跟踪您网站的用户。然而,缺点可能会减慢你自己的服务速度。字体对资源要求很高。我还没有在这个问题上做过任何测试,并且想知道是否有人有类似的想法。

答案 13 :(得分:1)

我在一项艰巨的任务中使用了grunt-local-googlefont

module.exports = function(grunt) {

    grunt.initConfig({
       pkg: grunt.file.readJSON('package.json'),

        "local-googlefont" : {
            "opensans" : {
                "options" : {
                    "family" : "Open Sans",
                    "sizes" : [
                        300,
                        400,
                        600
                    ],
                    "userAgents" : [
                        "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0)",  //download eot
                        "Mozilla/5.0 (Linux; U; Android 4.1.2; nl-nl; GT-I9300 Build/JZO54K) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30", //download ttf
                        "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1944.0 Safari/537.36" //download woff and woff2
                    ],
                    "cssDestination" : "build/fonts/css",
                    "fontDestination" : "build/fonts",
                    "styleSheetExtension" : "css",
                    "fontDestinationCssPrefix" : "fonts"

                }
            }
        }
    });

    grunt.loadNpmTasks('grunt-local-googlefont');
 };

然后,检索它们:

grunt local-googlefont:opensans

请注意,我使用了原始的fork,在检索名称中带有空格的字体时效果更好。

答案 14 :(得分:0)

k0pernicus之外,我还建议best-served-local。它也是一个bash(v4)脚本,使网络服务器运营商能够从他们自己的网络服务器下载和提供谷歌网络字体。但除了其他bash脚本之外,它还允许用户完全自动化(通过cron等)提供最新的字体文件和css文件。

答案 15 :(得分:0)

有一个非常简单的脚本,用纯Java编写,可以从Google Web Font链接下载所有字体(支持多种字体)。它还会下载CSS文件并使其适应本地文件。用户代理可以适用于获得除WOFF2之外的其他文件。见https://github.com/ssc-hrep3/google-font-download

生成的文件可以轻松添加到构建过程中(例如像vue-webpack这样的webpack构建。)

答案 16 :(得分:0)

您可以从https://github.com/google/fonts下载源字体

之后,使用font-ranger工具将大型Unicode字体拆分为多个子集(例如拉丁语,西里尔字母)。您应该使用该工具执行以下操作:

  • 为您支持的每种语言生成子集
  • 使用unicode-range子设置节省带宽
  • 从字体中删除膨胀并针对网络进行优化
  • 将字体转换为压缩的woff2格式
  • 为较旧的浏览器提供.woff后备广告
  • 自定义字体加载和渲染
  • 使用@ font-face规则生成CSS文件
  • 自托管网络字体或在本地使用

字体游侠https://www.npmjs.com/package/font-ranger

P.S。您也可以使用Node.js API自动化

答案 17 :(得分:0)

最简单的方法-使用google-webfonts-helper

让我们说我们要托管字体Red Rose

  • 打开google-webfonts-helper并在左上角过滤所需字体(键入 Red Rose 并输入..)
  • 从字符集中选择(默认为 latin ;如果需要扩展支持,请选择其他字符,例如 latin-ext
  • 选择样式(默认为
  • Copy CSS标签中
    • 如果您只想支持现代浏览器(woff2,woff),请选择Modern Browser
    • 如果要支持所有浏览器,请选择Best Support(我选择了此选项-woff2,woff,ttf,svg,eot)
  • 如果您的字体文件不在../fonts/路径中,则可以对其进行编辑以表示您的实际路径(对我来说,它是../assets/fonts/
  • 复制CSS并保留以备将来使用
  • 下载名为red-rose-v1-latin-ext_latin的zip文件;将其解压缩,然后将所有字体直接放入您的assets/fonts目录中(基于您之前提供的内容)
  • 在要嵌入样式表中,粘贴复制的CSS。如果您选择these options
  • ,它将看起来如下所示
/* red-rose-regular - latin-ext_latin */
@font-face {
  font-family: 'Red Rose';
  font-style: normal;
  font-weight: 400;
  src: url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.eot'); /* IE9 Compat Modes */
  src: local('Red Rose Regular'), local('RedRose-Regular'),
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.woff2') format('woff2'), /* Super Modern Browsers */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.woff') format('woff'), /* Modern Browsers */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.ttf') format('truetype'), /* Safari, Android, iOS */
       url('../assets/fonts/red-rose-v1-latin-ext_latin-regular.svg#RedRose') format('svg'); /* Legacy iOS */
}
/* Red Rose will now be available for use in your stylesheet, provide this font */

:root {
  font-family: 'Red Rose', cursive, sans-serif;
}
  • 就是这样!

答案 18 :(得分:-1)

如果您正在使用Nuxt,则可以为此使用他们专用的模块:https://github.com/nuxt-community/google-fonts-module 对我来说,它比webfonts助手好得多,后者通常在构建和生成没有Unicode范围的CSS文件时无法下载字体。