logo hsb.horse
← Zur Blog-Übersicht

Blog

Hinweise zu fehlgeschlagenen Versuchen, WOFF-Dateien von Google Fonts im Browser abzurufen

Eine Aufzeichnung von Versuchen und Irrtümern, ttf/otf/woff-Dateien von Google Fonts auf der Clientseite abzurufen und sie mit @vercel/satori zu verwenden. Einschränkungen des User-Agent-Headers und Probleme mit der Nichtkompatibilität von Woff2 wurden behoben.

Veröffentlicht:

Ich wollte ein Bild mit Vercel/Satori im Browser erstellen.

Wenn Sie die Schriftartdateien selbst hosten, können Sie Satori problemlos verwenden, möchten dies jedoch nach Möglichkeit nicht selbst hosten (es wird problematisch, wenn die Anzahl der unterstützten Schriftarten steigt).

Ich habe versucht, eine Schriftartendatei über Google Font herunterzuladen und zu prüfen, ob sie mit Satori verwendet werden kann, aber im Endeffekt ist es fehlgeschlagen.

Abschluss

Dies kann erreicht werden, wenn Satori woff2 unterstützt, aber es kann nicht nur mit dem Frontend (Clientseite) erreicht werden, das es derzeit nicht unterstützt.

Dies kann erreicht werden, wenn eine Serverseite vorhanden ist.

Anforderungen

  • Keine Serverseite
  • Es wird davon ausgegangen, dass der Benutzer den Namen und Stil der Schriftart, die er verwenden möchte, aus [Google Fonts] (https://fonts.google.com/) auswählt und in das Eingabefeld eingibt.

Angenommener Verarbeitungsablauf

  1. Der Benutzer gibt den Namen und Stil der Schriftart ein
  2. Holen Sie sich CSS von der Google Fonts API
  3. Extrahieren Sie die URL der Schriftartdatei aus CSS
  4. Laden Sie die Schriftartdatei herunter
  5. Bilderzeugung mit Satori

CSS-Abruf

Google Font ändert das Format der zurückgegebenen Schriftartdatei abhängig vom Benutzeragenten. Daher habe ich versucht, dieses Problem zu lösen, indem ich den User-Agent-Header neu geschrieben habe.

Wenn Sie jedoch sorgfältig darüber nachdenken, kann dieser nicht überschrieben werden, da es sich um einen verbotenen Header handelt, und der Plan ist hier ins Stocken geraten.

export const USER_AGENTS_BY_FONT_TYPE = {
// IE11 as woff
woff: "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko",
// Googlebot as truetype
ttf: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)",
};
export type FontType = keyof typeof USER_AGENTS_BY_FONT_TYPE;
export async function fetchGoogleFontCSS(
url: string,
fontType: FontType = "ttf"
) {
const response = await fetch(url, {
headers: {
"User-Agent": USER_AGENTS_BY_FONT_TYPE[fontType],
},
});
if (!response.ok) {
throw new Error(
`Failed to load font: ${response.status} ${response.statusText}`
);
}
return response.text();
}

User-Agent kann nicht mit fetch überschrieben werden, da es sich um einen [verbotenen Header] (https://developer.mozilla.org/ja/docs/Glossary/Forbidden_header_name) handelt.

Daten aus CSS extrahieren

Wenn Sie CSS erhalten können, ist die Implementierung wie folgt.

const subsetRegex = /\/\* (.+?) \*\//;
const fontFileRegex = /src: url\((.+?)\)/;
type ExtractResult = {
subsets: Record<string, string>;
hasItems: boolean;
};
const extract = (regex: RegExp, line: string) => regex.exec(line)?.[1];
export function extractFontFromCSS(css: string): ExtractResult {
const subsets: Record<string, string> = {};
let currentSubset = "";
for (const line of css.split("\n")) {
const subset = extract(subsetRegex, line);
if (subset) {
currentSubset = subset;
continue;
}
const url = extract(fontFileRegex, line);
if (url && !subsets[currentSubset]) {
subsets[currentSubset] = url;
}
}
return {
subsets,
hasItems: Object.keys(subsets).length > 0,
};
}

Am Ende

Also kam ich zu dem Schluss, dass ich eine Serverseite oder einen Proxy brauchte.

Aufgrund von Einschränkungen seitens des Browsers (verbotene Header, nur Auslieferung von woff2) haben wir darauf verzichtet, es nur auf der Clientseite zu implementieren.

Referenzmaterialien

Zusammenfassung

Ich habe versucht, woff/ttf von Google Fonts im Browser abzurufen, aber es scheiterte aufgrund von User-Agent-Einschränkungen und Satoris Inkompatibilität mit woff2.

Muss über die Serverseite oder den Proxy erfolgen. Halten Sie fest, was Sie aus Ihren Fehlern gelernt haben.