Jak hostować czcionki internetowe Google na własnym serwerze?

271

Potrzebuję użyć czcionek Google w aplikacji intranetowej. Klienci mogą, ale nie muszą mieć połączenia z Internetem. Po przeczytaniu warunków licencji wydaje się, że jest to prawnie dozwolone.

Samarth Bhargava
źródło
6
Rozumiem, że nie jest tak proste, jak pobranie jednego pliku i zapisanie go. Każda przeglądarka obsługuje inny format czcionek, a Google nie zapewnia bezpośredniego i łatwego sposobu uzyskania wszystkich niezbędnych plików, aby czcionka działała poprawnie we wszystkich przeglądarkach.
Samarth Bhargava
1
Wszystkie identyfikatory URI są pobierane z połączonego arkusza stylów.
fuxia
38
Tak, sam potrafię wyliczyć wszystkie szczegóły lub zadać pytanie, czy ktoś już to zrobił i czy ma doświadczenia i skrypty do podzielenia się
Samarth Bhargava
2
Cóż, Google zwraca różne odpowiedzi w fonts.googleapis.com/css?zależności od nagłówków UA (czytaj: Twoja przeglądarka) ➝ Dostarczają tylko to, czego potrzebuje aktualna przeglądarka. Jeśli chcesz uzyskać wszystkie potrzebne czcionki (lub nawet adresy URL), będziesz potrzebował wielu ładowań pliku css z różnych przeglądarek lub innych przeglądarek. z różnymi kutymi nagłówkami, aby uzyskać wszystko, czego potrzebujesz.
Frank Nocke,
Użyj tego narzędzia: npmjs.com/package/font-ranger
Do Async

Odpowiedzi:

217

Proszę pamiętać, że moja odpowiedź bardzo się postarzała.

Poniżej znajdują się inne bardziej zaawansowane technicznie odpowiedzi, np .:

więc nie pozwól, aby fakt, że jest to obecnie akceptowana odpowiedź, sprawia wrażenie, że jest ona nadal najlepsza.


Możesz teraz także pobrać cały zestaw czcionek Google za pośrednictwem github w ich repozytorium google / font . Zapewniają również migawkę czcionek o wielkości ~ 420 MB .


Najpierw pobierasz swój wybór czcionek jako spakowany pakiet, zapewniając ci kilka czcionek prawdziwego typu. Skopiuj je w miejscu publicznym, do którego możesz utworzyć link z css.

Na stronie pobierania google webfont znajdziesz link dołączający w następujący sposób:

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

Odsyła do CSS definiującego czcionki za pomocą @font-faceszeregu definicji.

Otwórz go w przeglądarce, aby skopiować i wkleić do własnego CSS oraz zmodyfikować adresy URL, aby zawierały odpowiedni plik czcionki i typy formatów.

Więc to:

@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');
}

staje się to:

/* 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');
}

Jak widać, wadą hostowania czcionek we własnym systemie w ten sposób jest to, że ograniczasz się do prawdziwego formatu tekstu, podczas gdy usługa Google Webfont określa przez urządzenie uzyskujące dostęp, które formaty będą przesyłane.

Ponadto musiałem dodać .htaccessplik do katalogu zawierającego czcionki zawierające typy mime, aby uniknąć błędów pojawiających się w Chrome Dev Tools.

W tym rozwiązaniu potrzebny jest tylko prawdziwy typ, ale zdefiniowanie większej wartości nie zaszkodzi, jeśli chcesz dołączyć także inne czcionki, np font-awesome.

#.htaccess
AddType application/vnd.ms-fontobject .eot
AddType font/ttf .ttf
AddType font/otf .otf
AddType application/x-font-woff .woff
k0pernikus
źródło
37
Nie jesteś ograniczony do TrueType, musisz tylko pobrać pliki .woff, tj. umieść „http: //themes.googleusercontent.com/static/fonts/cantarell/v3/...80lGh-uXM.woff” w przeglądarce, zapisz go jako „/fonts/Cantarell-Bold.woff” i zaktualizuj css to match (url ('/ fonts / Canterell-Bold.woff'))
Anthony Briggs
2
Istnieje powód, dla którego Google udostępnia kilka formatów czcionek - TrueType nie działa na starych przeglądarkach . WOFF jest standardem W3C.
Michael McGinnis,
3
Przewiń w dół do rozwiązania skryptu bash - super!
Dr. Max Völkel,
3
Plik zmienia zawartość w zależności od używanej przeglądarki.
Krii
3
Ta odpowiedź jest bardziej złożona do wdrożenia niż alternatywy wymienione poniżej; jest również technicznie niepoprawny pod wieloma względami (bez ograniczenia do TTF, TTF jest złym pomysłem, da to różne wyniki dla przeglądarki, nie możesz hostować czcionek w miejscach publicznych, ponieważ ma to samo pochodzenie). Nie rób tego, użyj jednej z pozostałych odpowiedzi poniżej.
Robin Berjon
202

Istnieje narzędzie localfont.com, które pomaga pobrać wszystkie warianty czcionek. Generuje również odpowiedni CSS do implementacji. przestarzałe

localfont nie działa. Zamiast tego, jak sugeruje Damir , możesz użyć google-webfonts-helper


udondan
źródło
Chociaż jest to fantastyczne, gdy potrzebujesz innych wersji językowych czcionki, musisz znaleźć inne rozwiązanie
anges244
Co z różnymi zestawami znaków?
vitro
1
Tutaj programista Google twierdzi, że samodzielne hostowanie czcionek Google ma swoje wady , zamiast tego zapoznaj się z tymi wskazówkami, aby użyć czcionek Google CDN i zwiększyć szybkość strony.
shaijut
@PauloCoghi Narzędzie może zgłaszać, że strona jest dostępna, ale najwyraźniej coś jest nie tak, ponieważ ja i wiele innych osób nie jesteśmy w stanie jej wyświetlić.
Lawyerson
147

Świetnym rozwiązaniem jest pomocnik google-webfonts-helper .

Pozwala wybrać więcej niż jeden wariant czcionki, co oszczędza dużo czasu.

Damir Bulic
źródło
Świetne narzędzia! Kocham to. Możesz zobaczyć podgląd czcionek i pobrać wszystkie wymagane pliki jednym kliknięciem.
cuixiping
Bardzo fajne narzędzie. Działa bardzo dobrze i pozwala również pobierać latin-extczcionki.
piotrekkr
3
To najlepsza opcja. Robi wszystko, możesz nawet określić prefiks folderu czcionek.
Maciej Krawczyk
63

Napisałem skrypt bash, który pobiera plik CSS na serwerach Google przy użyciu różnych aplikacji klienckich, pobiera różne formaty czcionek do lokalnego katalogu i zapisuje plik CSS zawierający je. Pamiętaj, że skrypt wymaga wersji Bash 4.x.

Zobacz https://neverpanic.de/blog/2014/03/19/downloading-google-web-fonts-for-local-hosting/ dla skryptu (nie odtwarzam go tutaj, więc muszę go tylko zaktualizować w jedno miejsce, kiedy muszę).

Edycja: przeniesiono do https://github.com/neverpanic/google-font-download

nigdy niepanic
źródło
4
To więcej niż niesamowite! (Mam nadzieję, że działa dobrze, jeszcze nie przetestowany). Przez lata szukałem czegoś takiego. Bez żartów, zacząłem nawet pisać własny skrypt, który jest daleki od ukończenia. Powoduje, że tak niewielu ludzi tego chce. Google ukrywa te czcionki za wygenerowanymi ciągami i nie udostępnia plików open source w rzeczywistości plików repo tylko w ttf. Chcą, abyśmy używali ich czcionek, chcą, abyśmy korzystali z ich serwerów, ponieważ wykorzystują to do śledzenia ludzi. Nawet osoby dbające o prywatność osadzają czcionki z serwera Google.
redanimalwar
1
Moją jedyną troską są rzeczywiste licencje czcionek, nie bardzo dokładnie je studiowałem. Wiem tylko, że licencje czcionek różnią się od GPL lub MIT. Czy więc rzeczywiście możemy legalnie łapać te czcionki z serwerów Google i serwować je na własną rękę? Znów nie wierzę ani przez chwilę, że Google rozdaje wszystkie te czcionki tylko po to, by ulepszyć świat, w rzeczywistości płacą deweloperom za tworzenie dla nich otwartych czcionek, więc na pewno coś zyskają, dużo danych. A jeśli nie zależy Ci na prywatności, możesz w ten sposób przetestować te czcionki lokalnie bez Internetu.
redanimalwar
2
Tę odpowiedź należy bardziej docenić, ponieważ ten skrypt może pobierać wszystkie formaty i podzbiory czcionek w przeciwieństwie do localfont.com.
piotrekkr
Wiem, że weźmiesz mnie za leniwą osobę, ale jako przeciętny użytkownik systemu Windows, trudno jest go skompilować itp., Aby móc z niego korzystać ...
Lucas Bustamante
@LucasB Kompilacja nie jest zaangażowana. To jest skrypt bashowy. Wiem, że Windows nie jest dostarczany z Bash, ale możesz go ponownie wdrożyć w sposób, który obsługuje Windows. To po prostu nie było częścią mojego przypadku użycia, więc nie spędziłem nad tym czasu.
neverpanic
14

Zawartość pliku CSS (z dołączonego adresu URL) zależy od przeglądarki, z której go przeglądam. Na przykład podczas przeglądania strony http://fonts.googleapis.com/css?family=Open+Sans za pomocą Chrome plik zawierał tylko linki WOFF. Używając Internet Explorera (poniżej), zawiera zarówno EOT, jak i WOFF. Wkleiłem wszystkie linki do przeglądarki, aby je pobrać.

@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');
}

Gdy hostujesz własne czcionki internetowe, musisz poprawnie połączyć się z każdym typem czcionki , poradzić sobie ze starszymi błędami przeglądarki itp. Gdy używasz czcionek internetowych Google (hostowanych przez Google), Google automatycznie łączy się z odpowiednimi typami czcionek dla tej przeglądarki.

Michael McGinnis
źródło
1
+1 za link do tego artykułu wyjaśniającego „uniwersalny” kod CSS do użycia i „zredukowany” do współczesnych przeglądarek!
ItalyPaleAle
2
Będę musiał więc inteligentnie obsługiwać przeglądarkę w innym formacie. Wiem, że jest to bardzo odradzane, ale obsługujemy naszą stronę dla niektórych klientów w Chinach i jest to główny powód, dla którego chcemy ją hostować. Zablokowali większość zasobów Google.
Lionel Chan,
6

Jest to prawnie dozwolone, o ile przestrzegasz warunków licencji czcionki - zwykle OFL.

Potrzebny będzie zestaw formatów czcionek internetowych, a Generator czcionek Squirrel Webfont może je wytworzyć.

Ale OFL wymagał zmiany nazwy czcionek, jeśli są modyfikowane, a użycie generatora oznacza ich modyfikację.

davelab6
źródło
Lub, w zależności od kroju pisma, możesz po prostu pobrać zestaw Webfont bezpośrednio z wiewiórki czcionek. fontsquirrel.com/fonts/open-sans
Jack Frost
3

Mam skrypt napisany w PHP podobny do skryptu @neverpanic, który automatycznie pobiera zarówno CSS, jak i czcionki ( zarówno z podpowiedziami, jak i bez podpowiedzi ) z Google. Następnie obsługuje poprawne CSS i czcionki z twojego własnego serwera opartego na User Agent. Zachowuje własną pamięć podręczną, więc czcionki i CSS klienta użytkownika zostaną pobrane tylko raz.

Jest w przedwczesnym stadium, ale można go znaleźć tutaj: DaAwesomeP / php-offline-fonts

DaAwesomeP
źródło
2

Aby hostować wszystkie czcionki (lub niektóre z nich) na własnym serwerze, pobierz czcionki z tego repozytorium i używaj go tak, jak chcesz: https://github.com/praisedpk/Local-Google-Fonts

Jeśli chcesz to zrobić, aby rozwiązać problem buforowania przeglądarki przy użyciu czcionek Google Fonts, możesz użyć alternatywnych czcionek CDN i dołączyć czcionki jako:

<link href="https://pagecdn.io/lib/easyfonts/fonts.css" rel="stylesheet" />

Lub konkretna czcionka, jak:

<link href="https://pagecdn.io/lib/easyfonts/lato.css" rel="stylesheet" />
Hamid Sarfraz
źródło
1

Użyłem grunt-local-googlefont w zadaniu pomruku .

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');
 };

Następnie, aby je odzyskać:

grunt local-googlefont:opensans

Uwaga: używam widelca z oryginału, który działa lepiej podczas pobierania czcionek z białymi spacjami w ich nazwach.

Motek
źródło
1

Możesz faktycznie pobrać wszystkie warianty formatów czcionek bezpośrednio z Google i dołączyć je do swojego css, aby wyświetlać je z serwera. W ten sposób nie musisz się martwić, że Google śledzi użytkowników Twojej witryny. Jednak wadą może być spowolnienie własnej prędkości serwowania. Czcionki są dość wymagające pod względem zasobów. Nie wykonałem jeszcze żadnych testów w tym numerze i zastanawiam się, czy ktoś ma podobne myśli.

Flyhead
źródło
1

Jeśli korzystasz z pakietu Webpack, możesz zainteresować się tym projektem: https://github.com/KyleAMathews/typefaces

Na przykład powiedz, że chcesz użyć czcionki Roboto:

npm install typeface-roboto --save

Następnie wystarczy zaimportować go do punktu wejścia aplikacji (główny plik js):

import 'typeface-roboto'
justin
źródło
1

Możesz postępować zgodnie ze skryptem opracowanym przy użyciu PHP. Gdzie możesz pobrać dowolne czcionki Google za pomocą skryptu. Pobierze czcionki i utworzy plik CSS i zarchiwizuje do spakowania.
Możesz pobrać kod źródłowy z 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>";
        } 
    } 
}
Sourav
źródło
0

Oprócz k0pernicus chciałbym zaproponować najlepiej służył lokalnego . Jest to również skrypt bash (v4), który umożliwia operatorom serwerów pobierania i obsługiwania czcionek internetowych Google z własnego serwera. Ale oprócz drugiego skryptu bash, pozwala użytkownikowi w pełni zautomatyzować (za pomocą crona itp.) Obsługę aktualnych plików czcionek i plików css.

Ronald van Engelen
źródło
0

Istnieje bardzo prosty skrypt, napisany zwykłą Javą, do pobierania wszystkich czcionek z łącza Google Web Font (obsługiwane wiele czcionek). Pobiera również plik CSS i dostosowuje go do plików lokalnych. User-agent może być przystosowany do pobierania również innych plików niż tylko WOFF2. Zobacz https://github.com/ssc-hrep3/google-font-download

Pliki wynikowe można łatwo dodać do procesu kompilacji (np. Kompilacja webpacka vue-webpack).

ssc-hrep3
źródło
0

Możesz pobrać czcionki źródłowe z https://github.com/google/fonts

Następnie użyj font-rangernarzędzia do podzielenia dużej czcionki Unicode na wiele podzbiorów (np. Łaciński, cyrylica). Za pomocą tego narzędzia należy wykonać następujące czynności:

  • Generuj podzbiory dla każdego obsługiwanego języka
  • Użyj podzestawu zakresu Unicode, aby zaoszczędzić przepustowość
  • Usuń wzdęcia z czcionek i zoptymalizuj je pod kątem Internetu
  • Konwertuj czcionki na skompresowany format woff2
  • Zapewnij awarię .woff dla starszych przeglądarek
  • Dostosuj ładowanie i renderowanie czcionek
  • Wygeneruj plik CSS z regułami @ font-face
  • Własne hosty czcionek internetowych lub używaj ich lokalnie

Font-Ranger : https://www.npmjs.com/package/font-ranger

PS Możesz to również zautomatyzować za pomocą Node.js API

Wykonaj asynchronię
źródło