Подтвердить что ты не робот

В 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?

4b9b3361

Ответ 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 файл в той же папке, что и ваши файлы шрифтов.