В IE CSS font-face работает только при навигации по внутренним ссылкам
Наш веб-дизайнер создал CSS со следующим шрифтом:
@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;
}
Он отлично работает в IE и Firefix. Но есть проблема: на IE шрифты отображаются правильно, только когда я перемещаюсь по странице, используя внутренние ссылки на веб-страницы. Если я нажму кнопку Refresh или Back, шрифты будут заменены шрифтом по умолчанию (Times New Roman).
В настоящее время веб-сайт использует HTTPS, но такая же проблема наблюдается при использовании HTTP.
Когда я перемещаюсь с использованием внутренних ссылок веб-сайта, на вкладке "Сеть" инструментов разработчика IE (Shift-F12) я вижу следующее:
/Content/oxygen-regular-webfont.eot? GET 200 application/vnd.ms-fontobject
Когда я использую кнопки Refresh/Back, есть еще две записи для других шрифтов:
/Content/oxygen-regular-webfont.woff GET 200 application/x-font-woff
/Content/oxygen-regular-webfont.ttf GET 200 application/octet-stream
Файл CSS загружается следующим образом:
/Content/site.css GET 200 text/css
Я попытался удалить оба woff и ttf, чтобы у меня было следующее:
@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;
}
Но все же IE ведет себя одинаково (за исключением того, что он больше не загружает woff и ttf): отображает неправильные резервные шрифты при навигации по Back/Refresh.
Как заставить IE загружать правильные шрифты в действиях Refresh/Back?
Ответы
Ответ 1
Я нашел решение, но я не вижу причины, почему он работает (ну, только одна причина - это IE: D).
То, что я сделал, - это снова разместить тот же сайт на Apache и протестировать. На Apache шрифты отлично работали даже при использовании кнопки "Обновить". Затем в сетевом инспекторе я увидел, что Apache возвращает 304 вместо 200 для eot файла, и он ударил меня - так что это проблема кеширования. Я пошел в свое приложение ASP.NET и, конечно же, по соображениям безопасности (а также во избежание кеширования запросов AJAX) кто-то отключил каждое кэширование, которое вы могли себе представить:
// 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();
Как только я прокомментировал последние две строки кода, внезапно шрифты начали без проблем работать в IE. Поэтому я предполагаю, что ответ: IE не может загрузить шрифт, если он не кэширован. Я не знаю, почему проблема возникает только при обновлении/навигации назад.
Изменить - Альтернативное решение
Вместо того, чтобы комментировать последние две строки
// 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();
Измените SetAllowResponseInBrowserHistory
на true
:
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);
Это, по-моему, по-прежнему не позволяет кэшировать, за исключением обратной и передовой навигации.
MSDN - метод SetAllowResponseInBrowserHistory
Ответ 2
Я столкнулся с той же проблемой.
Если заголовок файла .eot содержит значение Cache-Control: no-cache, IE9 неправильно загружает шрифт.
Dev Tools показал Результат - 200, но столбец Получено показал 400B, в то же время Content-Length был 70Kb.
Я использовал следующее значение Cache-Control: max-age = 0, чтобы устранить проблему.
Ответ 3
У меня просто была такая же ошибка, и для тех, кто хочет иметь чистое решение (не связанное с точной технологией): вы должны убедиться, что заголовки шрифтов, которые вы отправляете, не говорят no-cache
. В дополнение к тому, что было написано ранее, на самом деле есть два заголовка, которые могут это сделать:
"cache-control: no-cache"
и
"pragma: no-cache"
Оба из них говорят, что браузер тот же, первый из них является частью HTTP1.1, второй старше (HTTP1.0).
Теперь решения:
- Если вы действительно хотите использовать шрифты (и другие файлы?) без
кеширование на стороне клиента, установите
"cache-control" to "max-age=0"
; вы можете удалить заголовок прагмы, он устарел (или установить его на "pragma: cache"
).
- Если вы действительно хотите иметь кеширование: удалите значения
no-cache
и установите правильный максимальный возраст (например, "cache-control: max-age=3600"
- кеш-час). Pragma может быть установлен на "pragma: cache"
или полностью удален.
Ответ 4
Я нашел альтернативное решение для решения этой проблемы.
Я встроил шрифт непосредственно в таблицу стилей вместо загрузки в качестве отдельного файла шрифта. Это работает абсолютно нормально во всех браузерах, включая Windows, Mac, IOS, Android и т.д. И помогает сократить количество HTTP-запросов на веб-странице.
Это не потребует каких-либо изменений в заголовке 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;
}
Вы можете использовать встроенную команду base64 в OS X или Linux для кодирования шрифтов.
Ответ 5
JustAMartin ответ привел нас к другому решению:
Вместо того, чтобы комментировать последние две строки
// 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();
Мы добавили следующую строку:
HttpContext.Current.Response.Cache.SetAllowResponseInBrowserHistory(true);
Это, по-моему, по-прежнему не позволяет кэшировать, за исключением обратной и передовой навигации.
MSDN - метод SetAllowResponseInBrowserHistory
Ответ 6
Удаление глобального ответа. Параметры NoCache и NoStore исправят шрифты, но если вам нужны эти настройки, то, очевидно, это не ответ.
Я понимаю, что установка устаревших кешей не приведет к постоянному предотвращению отображения кэшированных страниц; он заставляет проверку на сервер, но если страница не изменяется (304 ответ), может (обычно?) по-прежнему отображать кешированную версию.
(На самом деле, прочитав это сейчас, мне пришло в голову, что установка кеша клиента немедленно истекает в сочетании с SetNoServerCaching может заставить страницу клиента всегда обновляться? Похоже, что это может иметь последствия для производительности.)
Я обнаружил, что в ASP.NET MVC с использованием атрибута OutputCacheAttribute на контроллере для отключения кэширования не прерываются IE-шрифты.
[OutputCacheAttribute(VaryByParam = "*", Duration = 0, NoStore = true)]
public class FooController : Controller
{
...
}
Я понимаю, что NoStore - это не то же самое, что SetCacheability (HttpCacheability.NoCache), но он, похоже, работает для этой цели.
Вы можете создать базовый контроллер с атрибутом для наследования, чтобы очистить код.
Ответ 7
Убедитесь, что это не проблема, например, ваш CSS файл относительно того, где находятся шрифты. В вашем случае вам нужен ваш CSS файл в той же папке, что и ваши файлы шрифтов.
Ответ 8
Не устанавливайте заголовок запроса Vary на https
Загрузка шрифтов
Vary:Accept-Encoding,https
Работы
Vary:Accept-Encoding
Настройка заголовка кэша необходима для для предотвращения загрузки отложенных шрифтов.