내 서버에서 Google 웹 글꼴을 호스팅하는 방법은 무엇입니까?


271

인트라넷 응용 프로그램에서 일부 Google 글꼴을 사용해야합니다. 클라이언트는 인터넷에 연결되어 있거나 없을 수 있습니다. 라이센스 조건을 읽으면 법적으로 허용 된 것으로 보입니다.


6
내가 이해하는 것은 하나의 파일을 다운로드하여 저장하는 것만 큼 간단하지 않다는 것입니다. 각 브라우저는 서로 다른 글꼴 형식을 지원하며 Google은 모든 브라우저에서 글꼴이 올바르게 작동하도록 필요한 모든 파일을 얻을 수있는 직접적이고 쉬운 방법을 제공하지 않습니다.
Samarth Bhargava

1
연결된 스타일 시트에서 모든 URI를 가져옵니다.
fuxia

38
그렇습니다. 모든 세부 사항을 직접
알아볼 수도

2
글쎄, 구글은 fonts.googleapis.com/css?UA 헤더 (읽기 : 브라우저)에 따라 다른 답변을 반환합니다 . they 따라서 현재 브라우저에 필요한 것만 제공합니다. 필요한 모든 글꼴 (또는 URL 만)을 얻으려면 다른 브라우저 resp에서 css 파일을 여러 번로드해야합니다. 필요한 모든 것을 얻기 위해 다른 단조 헤더로.
Frank Nocke

이 도구를 사용하십시오 : npmjs.com/package/font-ranger
Async

답변:


217

내 답변이 오래되었다는 것을 명심하십시오.

아래에 기술적으로 더 정교한 다른 답변이 있습니다.

이것이 현재 허용되는 답변이라는 사실이 이것이 여전히 최고라는 인상을주지 않도록하십시오.


또한 github의 Google / font 저장소 에서 Google의 전체 글꼴 세트를 다운로드 할 수도 있습니다 . 또한 글꼴~ 420MB zip 스냅 샷 도 제공합니다 .


먼저 글꼴 선택을 압축 패키지로 다운로드하여 다양한 트루 타입 글꼴을 제공합니다. CSS에서 링크 할 수있는 공용 위치에 복사하십시오.

Google 웹 폰트 다운로드 페이지에 다음과 같은 포함 링크가 있습니다.

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

여러 정의를 통해 글꼴을 정의하는 CSS에 연결됩니다 @font-face.

브라우저에서 파일을 복사하여 자신의 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 웹 글꼴 서비스가 액세스하는 장치가 어떤 형식을 전송할지 결정하는 동안 실제 유형 형식으로 자신을 제한한다는 것입니다.

또한 .htaccessChrome 개발자 도구에서 오류가 발생하지 않도록 mime 유형이 포함 된 글꼴이 들어있는 디렉토리에 파일 을 추가 해야했습니다.

이 솔루션의 경우 진정한 유형 만 필요하지만 더 많은 것을 정의해도 다른 글꼴을 포함하려는 경우에도 영향을 미치지 않습니다 font-awesome.

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

37
TrueType으로 제한되지 않고 .woff 파일도 다운로드하면됩니다. 'http : //themes.googleusercontent.com/static/fonts/cantarell/v3/...80lGh-uXM.woff'를 웹 브라우저에 넣고 '/fonts/Cantarell-Bold.woff'로 저장 한 다음 일치하는 CSS (url ( '/ fonts / Canterell-Bold.woff'))
Anthony Briggs

2
Google에서 여러 글꼴 형식을 제공하는 이유가 있습니다 . 이전 브라우저에서는 TrueType이 작동하지 않습니다 . WOFF는 W3C 표준입니다.
마이클 맥기니스

3
bash 스크립트 솔루션으로 스크롤하십시오.
맥스 볼켈 박사

3
파일은 사용중인 브라우저에 따라 내용을 변경합니다.
Krii

3
이 응답은 아래 나열된 대안보다 배포하기가 더 복잡합니다. 또한 여러 측면에서 기술적으로 잘못되었습니다 (TTF에 대한 제한은 없으며 TTF는 나쁜 생각입니다. 브라우저마다 다른 결과를 얻을 수 있습니다. 동일한 출처가 적용되므로 공개적으로 글꼴을 호스팅 할 수는 없습니다). 그렇게하지 마십시오. 아래 다른 답변 중 하나를 사용하십시오.
Robin Berjon

202

localfont.com 도구 를 사용하면 모든 글꼴 변형을 다운로드 할 수 있습니다. 또한 구현을 위해 해당 CSS를 생성합니다. 더 이상 사용되지 않음

localfont가 다운되었습니다. 대신 Damir가 제안한 대로 google-webfonts-helper를 사용할 수 있습니다



당신이 당신의 글꼴의 다른 언어 버전을 필요로하는 일이 때 환상적인 있지만, 다른 솔루션을 찾을 수있다
anges244

다른 문자 집합은 어떻습니까?
시험관

1
여기에 개발자를 말한다 구글 자체 호스팅 구글 글꼴은 자신의 단점이 대신이 확인, 을 사용 구글 글꼴 CDN 및 증가 페이지 속도를.
shaijut

@PauloCoghi이 도구는 웹 사이트에 접근 할 수 있다고보고하지만 다른 사람들이 볼 수 없기 때문에 문제가있는 것이 분명합니다.
Lawyerson

147

훌륭한 해결책은 google-webfonts-helper입니다. 입니다.

하나 이상의 글꼴 변형을 선택할 수있어 시간이 많이 절약됩니다.


훌륭한 도구! 나는 그것을 좋아한다. 한 번의 클릭으로 글꼴 미리보기를보고 필요한 모든 파일을 다운로드 할 수 있습니다.
cuixiping

아주 좋은 도구입니다. 잘 작동하며 latin-ext글꼴도 다운로드 할 수 있습니다.
piotrekkr

3
이것이 최선의 선택입니다. 글꼴 폴더 접두사를 지정할 수도 있습니다.
Maciej Krawczyk 2016 년

63

다른 사용자 에이전트가있는 Google 서버에서 CSS 파일을 가져 와서 다른 글꼴 형식을 로컬 디렉토리에 다운로드하고 CSS 파일을 포함 하는 bash 스크립트 를 작성했습니다. 스크립트에는 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
이것은 더 굉장합니다! (아직 테스트되지 않은 상태로 작동하기를 바랍니다). 나는 수년에 걸쳐이 양식과 같은 것을 검색했습니다. 농담이 아닙니다. 나는 심지어 완성되지 않은 내 자신의 대본을 쓰기 시작했습니다. 사람들이 이것을 원하지 않는 경향이 있습니다. Google 은이 글꼴을 생성 된 문자열 뒤에 숨기고 실제로 ttf에서만 실제로 웹 글꼴 파일을 오픈 소스하지 않습니다. 그들은 우리가 글꼴을 사용하기를 원하고 사람들을 추적하기 위해 이것을 악용하기 때문에 서버를 사용하기를 원합니다. 또한 개인 정보를 잘 알고있는 사람들조차도 Google 서버의 글꼴을 포함합니다.
redanimalwar

1
내 유일한 관심사는 실제 글꼴 라이센스이며, 실제로는 자세히 조사하지는 않습니다. 글꼴 라이센스는 GPL 또는 MIT와 다릅니다. 우리는 실제로 합법적으로 Google 서버에서이 글꼴을 가져 와서 자체 글꼴을 제공 할 수 있습니까? 다시 한 번 구글이 세상을 더 좋게 만들기 위해이 모든 글꼴을 제공한다고 생각하지는 않습니다. 실제로 개발자에게 오픈 글꼴을 만들기 위해 개발자에게 비용을 지불하여 무언가 많은 데이터를 얻습니다. 그리고 프라이버시가 없다면 인터넷 없이이 글꼴을 로컬에서 테스트 할 수 있습니다.
redanimalwar 2012

2
이 스크립트는 localfont.com과 달리 모든 글꼴 형식과 하위 집합을 다운로드 할 수 있기 때문에 더 많이 투표해야합니다.
piotrekkr

나는 당신이 나를 게으른 사람으로 데려 갈 것이란 것을 알고 있지만, 보통의 Windows 사용자는 그것을 사용하고 그것을 사용할 수 있도록 컴파일해야합니다 ...
Lucas Bustamante

@LucasB 관련된 컴파일이 없습니다. bash 스크립트입니다. Windows에는 Bash가 제공되지 않지만 Windows를 지원하는 방식으로 이것을 다시 구현하십시오. 그것은 단지 내 유스 케이스의 일부가 아니기 때문에 시간을 소비하지 않았습니다.
neverpanic

14

포함 URL의 CSS 파일 내용은 내가 보는 브라우저에 따라 다릅니다. 예를 들어 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 웹 글꼴 (Google에서 호스팅)을 사용하면 Google은 해당 브라우저에 맞는 올바른 글꼴 유형에 자동으로 링크합니다.


1
사용할 "유니버설"CSS 코드와 최신 브라우저에 대한 "감소 된"코드를 설명하는 기사로 연결되는 +1!
ItalyPaleAle

2
따라서 다른 형식으로 브라우저를 현명하게 제공해야합니다. 이 방법을 사용하지 않는 것이 좋지만 일부 중국 고객에게 페이지를 제공하고 있으며 이것이 호스팅하려는 주된 이유입니다. 그들은 대부분의 Google 리소스를 차단했습니다.
Lionel Chan

6

글꼴 라이센스 조건 (일반적으로 OFL)을 준수하는 한 법적으로 허용됩니다.

웹 글꼴 형식 집합이 필요하며 Font Squirrel Webfont Generator에서 이러한 글꼴 을 만들 수 있습니다.

그러나 OFL에서는 글꼴을 수정하면 이름을 바꾸어야했으며 생성기를 사용하면 글꼴을 수정해야합니다.


또는 서체에 따라 글꼴 다람쥐에서 직접 웹 폰트 키트를 얻을 수 있습니다. fontsquirrel.com/fonts/open-sans
Jack Frost

3

@neverpanic 과 비슷한 PHP로 작성된 스크립트가 있으며 CSS와 글꼴 ( 힌트 및 언 힌트 모두 )을 Google에서 자동으로 다운로드합니다 . 그런 다음 사용자 에이전트를 기반으로 자신의 서버에서 올바른 CSS 및 글꼴을 제공합니다. 자체 캐시를 유지하므로 사용자 에이전트의 글꼴과 CSS는 한 번만 다운로드됩니다.

초기 단계이지만 여기에서 찾을 수 있습니다 : DaAwesomeP / php-offline-fonts


2

자신의 서버에서 모든 글꼴 (또는 일부 글꼴)을 호스팅하려면이 리포지토리에서 글꼴을 다운로드하여 원하는 방식으로 사용하십시오. 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" />

1

내가 사용 꿀꿀 - 지역 - 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

참고로 원본에서 포크를 사용하고 있는데 이름에 공백이있는 글꼴을 검색 할 때 더 잘 작동합니다.


1

실제로 모든 글꼴 형식 변형을 Google에서 직접 다운로드하여 CSS에 포함시켜 서버에서 제공 할 수 있습니다. 그렇게하면 Google이 사이트 사용자를 추적하는 것에 대해 걱정할 필요가 없습니다. 그러나 단점은 자신의 서빙 속도를 늦출 수 있습니다. 글꼴은 리소스를 요구합니다. 나는이 문제에 대한 테스트를 아직 수행하지 않았으며 비슷한 생각을 가진 사람이 있는지 궁금합니다.




1

Webpack을 사용하는 경우이 프로젝트에 관심이있을 수 있습니다 : https://github.com/KyleAMathews/typefaces

예를 들어 Roboto 글꼴을 사용한다고 가정하십시오.

npm install typeface-roboto --save

그런 다음 앱의 진입 점 (기본 js 파일)으로 가져 오십시오.

import 'typeface-roboto'

1

PHP를 사용하여 개발 된 스크립트를 따를 수 있습니다. 스크립트를 사용하여 Google 글꼴을 다운로드 할 수있는 위치 글꼴을 다운로드하고 CSS 파일을 만들고 압축 파일을 압축합니다.
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>";
        } 
    } 
}

0

k0pernicus 외에도 best-served-local 을 제안하고 싶습니다 . 또한 웹 서버 운영자가 자신의 웹 서버에서 Google 웹 글꼴을 다운로드하여 제공 할 수 있도록하는 bash (v4) 스크립트입니다. 그러나 다른 bash 스크립트 외에도 사용자는 최신 글꼴 파일 및 css 파일의 제공을 cron 등을 통해 완전히 자동화 할 수 있습니다.


0

Google 웹 글꼴 링크 (여러 글꼴 지원)에서 모든 글꼴을 다운로드하기 위해 일반 Java로 작성된 매우 간단한 스크립트가 있습니다. 또한 CSS 파일을 다운로드하여 로컬 파일에 적용합니다. 사용자 에이전트는 WOFF2 이외의 다른 파일도 가져 오도록 조정할 수 있습니다. 보다 https://github.com/ssc-hrep3/google-font-download를

결과 파일은 빌드 프로세스 (예 :와 같은 웹팩 빌드 vue-webpack)에 쉽게 추가 할 수 있습니다 .


0

https://github.com/google/fonts 에서 소스 글꼴을 다운로드 할 수 있습니다.

그런 다음 font-ranger도구를 사용 하여 큰 유니 코드 글꼴을 여러 하위 집합 (예 : 라틴어, 키릴 자모)으로 분할하십시오. 도구를 사용하여 다음을 수행해야합니다.

  • 지원하는 각 언어에 대한 하위 집합 생성
  • 대역폭 절약을 위해 유니 코드 범위 하위 설정 사용
  • 글꼴에서 부풀림을 제거하고 웹에 맞게 최적화하십시오
  • 글꼴을 압축 된 woff2 형식으로 변환
  • 구형 브라우저에 .woff 대체 제공
  • 글꼴 로딩 및 렌더링 사용자 정의
  • @ font-face 규칙으로 CSS 파일 생성
  • 자체 호스팅 웹 글꼴 또는 로컬에서 사용

글꼴 위험 : https://www.npmjs.com/package/font-ranger

추신 Node.js API를 사용하여이를 자동화 할 수도 있습니다

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.