Как принудительно отключить режим совместимости IE со стороны сервера?
В среде, управляемой доменом, я обнаружил, что режим совместимости запускается на определенных клиентах (winXP/Win7, IE8/IE9), даже когда мы предоставляем теги X-UA, определение!DOCTYPE и ответ "IE=Edge" заголовки. На этих клиентах установлен флажок "отображать сайты интрасети в режиме совместимости". Именно это я и пытаюсь переопределить.
Ниже приведена документация, которую я использовал, чтобы понять, как IE решает активировать режим совместимости.
http://msdn.microsoft.com/en-us/library/ff406036%28v=VS.85%29.aspx
http://blogs.msdn.com/b/ie/archive/2009/02/16/just-the-facts-recap-of-compatibility-view.aspx
Владельцы сайтов всегда контролируют их содержание. Владельцы сайтов могут использовать тег X-UA-Compatible для полной декларации о том, как они хотели бы, чтобы их сайт отображался, и для отображения страниц в режиме стандартов на стандарты IE7. Использование тега X-UA-Compatible переопределяет представление совместимости на клиенте.
Google для "Определение совместимости документов", к сожалению, механизм СПАМа не позволяет мне публиковать более 2 URL.
Это ASP .NET
веб-приложение и включает следующие определения на главной странице:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
</head>
а также web.config
<system.webServer>
<httpProtocol>
<customHeaders>
<clear />
<add name="X-UA-Compatible" value="IE=Edge" />
</customHeaders>
</httpProtocol>
</system.webServer>
Я использовал Fiddler, чтобы проверить, что заголовок действительно вводится правильно.
Насколько я понимаю, эти параметры позволят мне изменить настройку браузера "Отображать сайты интрасети в представлении совместимости". Но в зависимости от клиента я обнаружил, что некоторые из них по-прежнему будут запускать режим совместимости. Кажется, что это также относится к уровню компьютера, а не к параметру группы политик, поскольку я получаю разные результаты, даже когда использую один и тот же набор учетных данных на разных клиентах.
Отключение флажка "Параметры просмотра в режиме совместимости" делает свое дело. Но реальная цель состоит в том, чтобы приложение отображалось одинаково независимо от настроек клиента.
Какие-нибудь мысли и что я мог бы упустить? Можно ли вообще заставить IE всегда отображать страницы, не вызывая режим Compat?
бесконечно благодарен,
Жауме
PS: сайт находится в разработке и, конечно, не в списке совместимости Microsoft, но я также проверил на всякий случай.
Google для "Понимание списка просмотра совместимости", к сожалению, механизм СПАМа не позволяет мне публиковать более 2 URL.
4 ответа
Я обнаружил проблемы с двумя распространенными способами сделать это:
Делаем это с пользовательскими заголовками (
<customHeaders>
) в web.config позволяет различным развертываниям одного и того же приложения иметь этот набор по-разному. Я вижу это как еще одну вещь, которая может пойти не так, поэтому я думаю, что лучше, если приложение определит это в коде. Кроме того, IIS6 не поддерживает это.Включая HTML
<meta>
тег на главной странице веб-форм или странице макета MVC выглядит лучше, чем указано выше. Однако, если некоторые страницы не наследуются от них, тег должен быть продублирован, поэтому существует потенциальная проблема с ремонтопригодностью и надежностью.Сетевой трафик может быть уменьшен только отправкой
X-UA-Compatible
заголовок для клиентов Internet Explorer.
Хорошо структурированные приложения
Если ваше приложение структурировано таким образом, что все страницы в конечном итоге наследуются от одной корневой страницы, включите <meta>
пометить, как показано в других ответах.
Устаревшие Приложения
В противном случае, я думаю, что лучший способ сделать это - автоматически добавить заголовок HTTP ко всем ответам HTML. Один из способов сделать это - использовать IHttpModule
:
public class IeCompatibilityModeDisabler : IHttpModule
{
public void Init(HttpApplication context)
{
context.PreSendRequestHeaders += (sender, e) => DisableCompatibilityModeIfApplicable();
}
private void DisableCompatibilityModeIfApplicable()
{
if (IsIe && IsPage)
DisableCompatibilityMode();
}
private void DisableCompatibilityMode()
{
var response = Context.Response;
response.AddHeader("X-UA-Compatible", "IE=edge");
}
private bool IsIe { get { return Context.Request.Browser.IsBrowser("IE"); } }
private bool IsPage { get { return Context.Handler is Page; } }
private HttpContext Context { get { return HttpContext.Current; } }
public void Dispose() { }
}
IE=edge
указывает, что IE должен использовать свой последний механизм рендеринга (а не режим совместимости) для отображения страницы.
Кажется, что модули HTTP часто регистрируются в файле web.config, но это возвращает нас к первой проблеме. Однако вы можете зарегистрировать их программно в Global.asax следующим образом:
public class Global : HttpApplication
{
private static IeCompatibilityModeDisabler module;
void Application_Start(object sender, EventArgs e)
{
module = new IeCompatibilityModeDisabler();
}
public override void Init()
{
base.Init();
module.Init(this);
}
}
Обратите внимание, что важно, чтобы модуль static
и не создан в Init
так что для каждого приложения есть только один экземпляр. Конечно, в реальном приложении контейнер IoC, вероятно, должен управлять этим.
преимущества
- Преодолевает проблемы, изложенные в начале этого ответа.
Недостатки
- Администраторы сайта не могут контролировать значение заголовка. Это может быть проблемой, если выходит новая версия Internet Explorer и негативно влияет на визуализацию сайта. Тем не менее, это может быть преодолено, если модуль считывает значение заголовка из файла конфигурации приложения, а не использует жестко запрограммированное значение.
- Это может потребовать модификации для работы с ASP.NET MVC.
- Это не работает для статических HTML-страниц.
PreSendRequestHeaders
событие в приведенном выше коде, похоже, не срабатывает в IIS6. Я еще не понял, как решить эту ошибку.
Изменение моего заголовка на следующее решает проблему:
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Обновление: более полезная информация Что делает ?
Может быть, этот URL поможет вам: Активация режимов браузера с помощью Doctype
Изменить: сегодня мы смогли переопределить представление совместимости с: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Для разработчиков Node/Express вы можете использовать промежуточное ПО и установить его через сервер.
app.use(function(req, res, next) {
res.setHeader('X-UA-Compatible', 'IE=edge');
next();
});