I caratteri sottostanno a una regola di origine incrociata da cui immagini e script sono esenti. Servine uno da un altro nome host senza l'intestazione giusta e il browser lo scarica, si rifiuta di usarlo e ripiega — così il file risulta 200 nel pannello di rete, e la console lo spiega in un messaggio che nessuno legge.
Il messaggio
Access to font at 'https://cdn.example.com/f/inter.woff2' from origin
'https://yourdomain.com' has been blocked by CORS policy
L'intestazione
# nginx, on the host SERVING the font
location ~* \.(woff2?|ttf|otf|eot)$ {
add_header Access-Control-Allow-Origin "https://yourdomain.com";
add_header Cache-Control "public, max-age=31536000, immutable";
}
# apache / litespeed
<FilesMatch "\.(woff2?|ttf|otf|eot)$">
Header set Access-Control-Allow-Origin "https://yourdomain.com"
</FilesMatch>
crossorigin sul precaricamento, se precarichi
<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin>
Senza crossorigin su quel tag il carattere viene scaricato DUE VOLTE: una dal precaricamento e una dal foglio di stile, perché sono considerate richieste diverse. La pagina risulta più lenta di quanto sarebbe stata senza alcun precaricamento.
La risposta più semplice
Servi i caratteri dal tuo dominio. Stessa origine significa: nessuna questione di CORS, nessuna risoluzione DNS in più, nessuna seconda stretta di mano TLS e un terzo in meno nella pagina. Con HTTP/2 non esiste più nemmeno un argomento di velocità a favore di una rete di distribuzione dei caratteri.
# download once, commit them, serve from /fonts/
@font-face {
font-family: "Inter";
src: url("/fonts/inter.woff2") format("woff2");
font-display: swap;
}
font-display: swap mostra subito il carattere di riserva e lo sostituisce quando arriva quello vero. Senza, su una connessione lenta il testo resta invisibile fino a tre secondi.
