我需要在 Intranet 应用程序上使用一些 google 字体。客户端可能有也可能没有互联网连接。阅读许可条款,它似乎是合法的。
19 回答
请记住,我的回答已经过时了。
下面还有其他技术上更复杂的答案,例如:
因此,不要让这是当前公认的答案这一事实给您留下这仍然是最佳答案的印象。
您现在还可以通过 github 上的google/font存储库下载 google 的整个字体集。他们还提供了大约 420MB 的字体压缩快照。
您首先将您的字体选择下载为一个压缩包,为您提供一堆真正的字体。将它们复制到公共的地方,你可以从你的 CSS 链接到的地方。
在 google webfont 下载页面上,您会找到一个包含链接,如下所示:
http://fonts.googleapis.com/css?family=Cantarell:400,700,400italic,700italic|Candal
它通过一堆@font-face
定义链接到定义字体的 CSS。
在浏览器中打开它,将它们复制并粘贴到您自己的 CSS 中,并修改 url 以包含正确的字体文件和格式类型。
所以这:
@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 服务由访问设备决定将传输哪些格式。
此外,我必须在包含 mime 类型的字体的目录中添加一个.htaccess
文件,以避免在 Chrome 开发工具中弹出错误。
对于这个解决方案,只需要真正的类型,但是当你想要包含不同的字体时,定义更多也不会受到伤害,比如font-awesome
.
#.htaccess
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType application/x-font-woff .woff
有一个工具localfont.com可以帮助您下载所有字体变体。它还生成相应的 CSS 用于实现。 已弃用
localfont 已关闭。相反,正如Damir 建议的那样,您可以使用google-webfonts-helper
很好的解决方案是google-webfonts-helper 。
它允许您选择多个字体变体,从而节省大量时间。
我编写了一个bash 脚本,它使用不同的用户代理在 Google 的服务器上获取 CSS 文件,将不同的字体格式下载到本地目录并编写一个包含它们的 CSS 文件。请注意,该脚本需要 Bash 版本 4.x。
有关脚本,请参阅https://neverpanic.de/blog/2014/03/19/downloading-google-web-fonts-for-local-hosting/我需要的地方)。
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');
}
当您托管自己的网络字体时,您需要正确链接到每种字体类型,处理遗留浏览器错误等。当您使用 Google Web Fonts(由 Google 托管)时,Google 会自动链接到该浏览器的正确字体类型。
只要您遵守字体许可证的条款(通常是 OFL),它就是合法的。
您需要一组网络字体格式,Font Squirrel Webfont Generator可以生成这些格式。
但是 OFL 要求如果字体被修改,则需要重命名,使用生成器意味着修改它们。
我有一个用 PHP 编写的脚本,类似于@neverpanic的脚本,它会自动从 Google 下载 CSS 和字体(有提示和无提示)。然后它根据用户代理从您自己的服务器提供正确的 CSS 和字体。它保留自己的缓存,因此用户代理的字体和 CSS 只会下载一次。
它处于早期阶段,但可以在这里找到:DaAwesomeP / php-offline-fonts
最简单的方法 - 使用google-webfonts-helper
假设我们要托管字体Red Rose
:
- 打开google-webfonts-helper并在左上角过滤所需的字体(输入Red Rose并输入..)
- 从字符集中选择(默认为latin;如果您需要扩展支持,请选择其他字符,如latin-ext )
- 选择样式(默认为常规)
- 从
Copy CSS
选项卡- 如果
Modern Browser
您希望仅支持现代浏览器(woff2、woff),请选择 - 选择
Best Support
是否支持所有浏览器(我选择了这个 - woff2、woff、ttf、svg、eot)
- 如果
- 如果您的字体文件不在
../fonts/
路径中,您可以对其进行编辑以表示您的实际路径(对我来说是../assets/fonts/
) - 复制 CSS 并保留以备将来使用
- 下载名为
red-rose-v1-latin-ext_latin
;的 zip 文件 解压缩并将所有字体直接放入您的assets/fonts
目录(基于您之前提供的内容) - 在要嵌入的样式表中,粘贴复制的 CSS。如果您选择这些选项,它将如下所示
/* 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;
}
- 就这样!
由于您想在自己的服务器上托管所有字体(或其中的一些),因此您可以从此 repo 下载字体并以您想要的方式使用它:https ://github.com/praisedpk/Local-Google-Fonts
如果您只想这样做来解决 Google 字体附带的杠杆浏览器缓存问题,您可以使用替代字体 CDN,并将字体包括为:
<link href="https://pagecdn.io/lib/easyfonts/fonts.css" rel="stylesheet" />
或特定字体,如:
<link href="https://pagecdn.io/lib/easyfonts/lato.css" rel="stylesheet" />
编辑:正如 luckyrumo 所指出的,字体被贬低,有利于:https ://github.com/fontsource/fontsource
如果你使用 Webpack,你可能会对这个项目感兴趣:https ://github.com/KyleAMathews/typefaces
例如说你想使用 Roboto 字体:
npm install typeface-roboto --save
然后只需将其导入应用程序的入口点(主 js 文件):
import 'typeface-roboto'
我在 grunt 任务中使用了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,它在检索名称中带有空格的字体时效果更好。
实际上,您可以直接从 Google 下载所有字体格式变体,并将它们包含在您的 css 中以从您的服务器提供服务。这样您就不必担心 Google 会跟踪您网站的用户。但是,不利的一面可能会减慢您自己的服务速度。字体对资源要求很高。这个问题我还没有做过任何测试,不知道有没有人有类似的想法。
我的解决方案是从 google web fonts 下载 TTF 文件,然后使用onlinefontconverter.com。
我制作了一个很小的 PHP 脚本来从 Google 字体 CSS 导入 URL 获取下载链接,例如:https ://fonts.googleapis.com/css?family=Roboto:400,700|Slabo+27px|Lato:400,300italic,900italic
你可以在这里使用这个工具:http: //nikoskip.me/gfonts.php
例如,如果你使用上面的导入 URL,你会得到:
您可以按照使用 PHP 开发的脚本进行操作。您可以在哪里使用脚本下载任何谷歌字体。它将下载字体并创建一个 CSS 文件并存档到 zip。
您可以从 GitHub https://github.com/souravmsh/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>";
}
}
}
除了k0pernicus,我还想推荐best-served-local。它也是一个 bash (v4) 脚本,使网络服务器操作员能够从他们自己的网络服务器下载和提供 Google 网络字体。但除了其他 bash 脚本之外,它还允许用户完全自动化(通过 cron 等)提供最新的字体文件和 css 文件。
有一个非常简单的脚本,用纯 Java 编写,可以从 Google Web Font 链接下载所有字体(支持多种字体)。它还下载 CSS 文件并将其调整为本地文件。用户代理可以适应获取除 WOFF2 之外的其他文件。见https://github.com/ssc-hrep3/google-font-download
生成的文件可以很容易地添加到构建过程中(例如,类似的 webpack 构建vue-webpack
)。
您可以从https://github.com/google/fonts下载源字体
之后使用font-ranger
工具将您的大 Unicode 字体拆分为多个子集(例如拉丁文、西里尔文)。您应该使用该工具执行以下操作:
- 为您支持的每种语言生成子集
- 使用 unicode-range 子集来节省带宽
- 从字体中消除臃肿并针对网络进行优化
- 将您的字体转换为压缩的 woff2 格式
- 为旧版浏览器提供 .woff 后备
- 自定义字体加载和渲染
- 使用@font-face 规则生成 CSS 文件
- 自托管网络字体或在本地使用它们
字体游侠:https ://www.npmjs.com/package/font-ranger
PS 您也可以使用 Node.js API 自动执行此操作
如果你使用 Nuxt,你可以使用他们的专用模块:https ://github.com/nuxt-community/google-fonts-module 对我来说,它比 webfonts 帮助器好得多,它经常在下载构建过程中的字体和生成的没有 Unicode 范围的 CSS 文件。