Ответ 1
Я нашел проблемы с двумя обычными способами:
-
Выполнение этого с помощью настраиваемых заголовков (
<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. Я еще не понял, как решить эту проблему.