web-dev-qa-db-fra.com

Sur IE CSS font-face fonctionne uniquement lors de la navigation dans les liens internes

Notre webdesigner a créé un CSS avec la police de caractères suivante:

@font-face {
    font-family: 'oxygenregular';
    src: url('oxygen-regular-webfont.eot');
    src: url('oxygen-regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('oxygen-regular-webfont.woff') format('woff'),
         url('oxygen-regular-webfont.ttf') format('truetype'),
         url('oxygen-regular-webfont.svg#oxygenregular') format('svg');
    font-weight: normal;
    font-style: normal;
}

Cela fonctionne très bien sur IE et Firefix. Mais il y a un problème: sur IE, les polices ne sont rendues correctement que lorsque je navigue sur la page à l'aide de liens de page Web internes. Si je clique sur le bouton Actualiser ou Précédent, les polices sont remplacées par la police par défaut (Times New Roman).

Actuellement, le site Web utilise HTTPS, mais le même problème a été observé lors de l'utilisation de HTTP. 

Lorsque je navigue à l'aide de liens de sites Web internes, dans l'onglet Réseau de IE Outils de développement (Maj - F12), les éléments suivants s'affichent:

/Content/oxygen-regular-webfont.eot?    GET 200 application/vnd.ms-fontobject

Lorsque j'utilise les boutons Actualiser/Précédent, il existe également deux entrées pour les autres polices:

/Content/oxygen-regular-webfont.woff    GET 200 application/x-font-woff
/Content/oxygen-regular-webfont.ttf GET 200 application/octet-stream

Le fichier CSS lui-même est chargé de la manière suivante:

/Content/site.css   GET 200 text/css

J'ai essayé d'enlever les deux woff et ttf alors j'ai eu ce qui suit:

@font-face {
    font-family: 'oxygenregular';
    src: url('oxygen-regular-webfont.eot');
    src: url('oxygen-regular-webfont.eot?#iefix') format('embedded-opentype');
    font-weight: normal;
    font-style: normal;
}

Mais toujours IE se comporte de la même manière (sauf qu'il ne télécharge plus woff et ttf): affiche des polices de repli incorrectes lors de la navigation dans Retour/Rafraîchir.

Comment faire IE charger les polices correctes lors des actions de rafraîchissement/retour?

30
JustAMartin

J'ai trouvé une solution mais je ne vois pas la raison pour laquelle cela fonctionne (enfin, une seule raison - c'est IE: D).

Ce que j'ai fait était de mettre le même site sur Apache et de le tester à nouveau. Sur Apache, les polices fonctionnaient bien même lorsque vous utilisiez le bouton Actualiser. Ensuite, dans l'inspecteur du réseau, j'ai constaté qu'Apache en renvoyait 304 au lieu de 200 pour le fichier eot et cela m'a frappé - c'est donc un problème de mise en cache. Je suis allé à mon application ASP.NET et assez bien - pour des raisons de sécurité (et aussi pour éviter de mettre en cache les requêtes AJAX), quelqu'un avait désactivé chaque mise en cache que vous pouviez imaginer:

        // prevent caching for security reasons
        HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(false);
        HttpContext.Current.Response.Cache.SetExpires(DateTime.UtcNow.AddDays(-1));
        HttpContext.Current.Response.Cache.SetValidUntilExpires(false);
        HttpContext.Current.Response.Cache.SetRevalidation(HttpCacheRevalidation.AllCaches);
        HttpContext.Current.Response.Cache.SetNoServerCaching();

        // do not use any of the following two - they break CSS fonts on IE
        HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
        HttpContext.Current.Response.Cache.SetNoStore();

Dès que j'ai commenté les deux dernières lignes de code, les polices ont commencé à fonctionner sans problèmes avec IE. Donc, je suppose que la réponse est la suivante: IE ne peut pas charger la police si elle n'est pas mise en cache. Je n'ai aucune idée pourquoi le problème ne se produit que lors de l'actualisation/navigation en arrière, cependant.

Éditer - Solution alternative

Au lieu de commenter ces deux dernières lignes

    // do not use any of the following two - they break CSS fonts on IE
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetNoStore();

Changez plutôt SetAllowResponseInBrowserHistory en true:

HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);

Cela devrait toujours permettre l'absence de cache, à l'exception de la navigation en arrière et en avant si je comprends bien. MSDN - SetAllowResponseInBrowserHistory, méthode

22
JustAMartin

J'ai fait face au même problème.

Dans le cas où l'en-tête du fichier .eot le fichier contient Cache-Control: no-cache value, IE9 ne charge pas la police correctement. Les outils de développement ont montré Résultat - 200, mais la colonne Reçu a affiché 400B, dans le même temps Content-Length était 70Kb. J'ai utilisé la valeur suivante Cache-Control: max-age = 0 , pour résoudre le problème.

15
Alexandr Skachkov

Je viens d'avoir le même bogue, et pour ceux qui veulent une solution pure (non liée à la technologie exacte): vous devez vous assurer que les en-têtes de police que vous envoyez ne disent pas no-cache. En plus de ce qui a été écrit auparavant, il y a en fait deux en-têtes qui peuvent le faire: 

"cache-control: no-cache"

et

"pragma: no-cache"

Les deux disent que le navigateur est identique, le premier fait partie de HTTP1.1, le second est plus ancien (HTTP1.0).

Maintenant, des solutions:

  • Si vous souhaitez vraiment servir les polices (et autres fichiers?) Sans la mise en cache côté client, définissez "cache-control" to "max-age=0"; vous pouvez supprimer l'en-tête pragma, il est obsolète (ou définissez-le sur "pragma: cache").
  • Si vous souhaitez réellement utiliser la mise en cache: supprimez les valeurs no-cache et définissez l'âge maximal approprié (par exemple, "cache-control: max-age=3600" - cache d'une heure). Pragma peut être défini sur "pragma: cache" ou complètement supprimé.
6
Michal

J'ai trouvé une solution alternative pour résoudre ce problème. 

J'ai incorporé la police directement dans la feuille de style au lieu de la charger en tant que fichier de police séparé. Cela fonctionne parfaitement dans tous les navigateurs, y compris Windows, Mac, IOS, Android, etc. et aide à réduire le nombre de requêtes HTTP dans la page Web. 

Cela ne nécessitera aucune modification de l'en-tête Cache-Control. 

@font-face { font-family: '<FONT NAME>'; src: url(data:application/x-font-woff;charset=utf-8;base64,<BASE64_ENCODED>) format('woff'), url(data:application/x-font-ttf;charset=utf-8;base64,,<BASE64_ENCODED>) format('truetype'); font-weight: normal; font-style: normal; }

Vous pouvez utiliser la commande base64 intégrée sous OS X ou Linux pour le codage des polices.

4
Selvan K

JustAMartin 's answer nous a conduit à une solution différente:

Au lieu de commenter ces deux dernières lignes

    // do not use any of the following two - they break CSS fonts on IE
    HttpContext.Current.Response.Cache.SetCacheability(HttpCacheability.NoCache);
    HttpContext.Current.Response.Cache.SetNoStore();

Nous avons ajouté la ligne suivante:

HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);

Cela devrait toujours permettre l'absence de cache, à l'exception de la navigation en arrière et en avant si je comprends bien. MSDN - SetAllowResponseInBrowserHistory, méthode

3
Aldracor

La suppression de la réponse globale NoCache et NoStore sera corrigée par les paramètres, mais si vous avez besoin de ces paramètres, il est évident que ce n'est pas une réponse. 

D'après ce que je comprends, seul le fait de définir le cache sur expiré n'empêche pas systématiquement l'affichage des pages mises en cache. il oblige le serveur à vérifier, mais si la page n'est pas modifiée (réponse 304), il est toujours possible d'afficher la version mise en cache.

(En fait, en train de lire ceci maintenant, il m'est apparu que définir le cache client pour qu'il expire immédiatement, associé à SetNoServerCaching, pourrait forcer la page client à se renouveler en permanence. Cela semble toutefois avoir des conséquences sur les performances.)

J'ai constaté que dans ASP.NET MVC, l'utilisation de l'attribut OutputCacheAttribute sur un contrôleur pour désactiver la mise en cache ne casse pas les polices IE.

[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
public class FooController : Controller
{
    ...
}    

Je réalise que NoStore n’est pas identique à SetCacheability (HttpCacheability.NoCache), mais il semble fonctionner à cette fin.

Vous pouvez créer un contrôleur de base avec l'attribut dont vous héritez pour rendre le code plus propre.

2
Darren Rogers

Assurez-vous qu’il ne s’agit pas d’un problème de cheminement, c’est-à-dire que votre fichier CSS est relatif à l’emplacement des polices. Dans votre cas, vous avez besoin de votre fichier CSS dans le même dossier que vos fichiers de polices. 

1
jimmy

Ne définissez pas l'en-tête de demande Vary sur https

Aucun chargement de police

Vary:Accept-Encoding,https

Fonctionne

Vary:Accept-Encoding

La définition de l'en-tête de cache est nécessaire pour éviter le chargement de police retardé .

1
Matthias M