Как принудительно отключить режим совместимости IE со стороны сервера?

84

В среде, управляемой доменом, я обнаружил, что режим совместимости запускается на определенных клиентах (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 для "определения совместимости документов" , к сожалению, механизм спама не позволяет мне размещать более двух 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 всегда отображать страницы без запуска режима совместимости?

бесконечно благодарен,

Jaume

PS: сайт в настоящее время находится в разработке и, конечно, не входит в список совместимости Microsoft, но я на всякий случай тоже проверил.

Google для "Общие сведения о списке просмотра в режиме совместимости" , к сожалению, механизм спама не позволяет мне размещать более двух URL-адресов.

JSancho
источник

Ответы:

45

Я обнаружил проблемы с двумя распространенными способами:

  1. Выполнение этого с помощью настраиваемых заголовков ( <customHeaders>) в web.config позволяет различным развертываниям одного и того же приложения иметь этот набор по-разному. Я считаю, что это еще одна вещь, которая может пойти не так, поэтому я думаю, что лучше, если приложение укажет это в коде. Кроме того, IIS6 не поддерживает это .

  2. Включение <meta>тега HTML на главную страницу веб-форм или страницу макета MVC кажется лучше, чем указанное выше. Однако, если некоторые страницы не унаследованы от них, тег необходимо продублировать, поэтому существует потенциальная проблема с ремонтопригодностью и надежностью.

  3. Сетевой трафик можно уменьшить, отправив только 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. Я еще не понял, как исправить эту ошибку.
Сэм
источник
2
Чтобы получить ответ, могло потребоваться больше года, а фактическое приложение, над которым я работал, теперь устарело. Тем не менее, это определенно самый тщательный и хорошо проработанный ответ, на который я мог надеяться. Хорошие вещи приходят к тем, кто ждет :) спасибо, Сэм
JSancho
1
«Это должно гарантировать, что страница отображается в соответствии с другими браузерами и в соответствии со стандартами». Мне очень жаль, но это совсем не мой опыт. Прямо сейчас я работаю с отчетом SSRS, который отображает все неправильно в IE10, отлично работает в Chrome и почти нормально работает в режиме совместимости с IE10.
BobRodes
@BobRodes, я думаю, что написал это, потому что более поздние версии IE должны быть более совместимыми со стандартами, но я на самом деле не говорил по опыту, так что хороший замечание! Я только что обновил ответ, чтобы удалить это утверждение.
Sam
В отношениях со своими конкурентами Microsoft использует концепцию «объять, расширить, погасить». Во-первых, придерживайтесь любых стандартов. Затем «улучшите» стандарт, добавив проприетарные функции и возможности. Затем незаметно откажитесь от поддержки стандарта в будущих версиях. К счастью, у них проблемы с IE. :)
BobRodes 05
Это сработало для меня, и я попробовал несколько разных решений, включая метатег, и попытался использовать css-хаки для учета областей сайта, которые не отображались неправильно, т.е.
user609926
39

Изменение моего заголовка на следующее, решает проблему:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Гидеон
источник
Мне также нужно было добавить заголовок клиента в файл web.config, чтобы заставить его работать на сервере Windows 2008
Catch22,
17

Обновление: более полезная информация. Что делает <meta http-Equiv = "X-UA-Compatible" content = "IE = edge">?

Возможно, этот URL-адрес может вам помочь: Активация режимов браузера с помощью Doctype

Изменить: сегодня мы смогли переопределить представление совместимости с помощью: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

Андрей
источник
@Balanivash Это было действительно хорошее чтение, спасибо за ссылку. Статья наводит меня на мысль, что «режим совместимости» включен, потому что сайт находится в зоне интрасети. Однако это не происходит постоянно, например: - win7, IE8, на клиенте -> полный стандартный режим - win7, IE8, на другом компьютере с теми же учетными данными -> режим совместимости Чтобы быть в безопасности I ' m также запускает новые сеансы браузера и сбрасывает панель инструментов разработчика IE до значений по умолчанию при каждом тесте.
JSancho 01
Может быть, вы можете попробовать это: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Эндрю
1
Также: если вы хотите, чтобы ваше веб-приложение сообщало IE8, что он действительно вам доверяет, вам необходимо отправить X-UA-Compatible в виде HTTP-заголовка с вашего веб-сервера вместо метатега: social.msdn.microsoft.com/Forums/en- США / iewebdevelopment / thread /…
Эндрю
2
На самом деле сегодня мы смогли переопределить представление совместимости с:<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Эндрю
2
Спасибо, что обновили свой ответ. Думаю, было бы лучше, если бы ваш ответ был уточнен, IE=Edgeпоскольку речь идет об отключении режима совместимости.
Сэм
0

Для разработчиков Node / Express вы можете использовать промежуточное программное обеспечение и установить его через сервер.

app.use(function(req, res, next) {
  res.setHeader('X-UA-Compatible', 'IE=edge');
  next();
});
мбокил
источник