Jak wymusić wyłączenie trybu zgodności IE po stronie serwera?

84

W środowisku kontrolowanym przez domenę stwierdzam, że tryb zgodności jest uruchamiany na niektórych klientach (winXP / Win7, IE8 / IE9), nawet jeśli dostarczamy tagi X-UA, definicję! DOCTYPE i odpowiedź „IE = Edge” nagłówki. Ci klienci mają zaznaczone pole wyboru „wyświetlaj witryny intranetowe w widoku zgodności”. Właśnie to próbuję zastąpić.

Poniżej znajduje się dokumentacja, której użyłem, aby spróbować zrozumieć, w jaki sposób IE decyduje się faktycznie uruchomić tryb zgodności.

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

Właściciele witryn zawsze mają kontrolę nad swoją zawartością. Właściciele witryn mogą zdecydować się na użycie tagu kompatybilnego z X-UA, aby absolutnie zadeklarować sposób wyświetlania swojej witryny i mapować strony w trybie standardowym na standardy IE7. Użycie tagu kompatybilnego z X-UA zastępuje widok zgodności na kliencie.

Google za „Defining Document Compatibility” , niestety silnik SPAM nie pozwala mi publikować więcej niż 2 adresy URL.

To jest ASP .NETaplikacja internetowa i zawiera następujące definicje na stronie wzorcowej:

<!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>

i web.config

<system.webServer>
  <httpProtocol>
    <customHeaders>
      <clear />
      <add name="X-UA-Compatible" value="IE=Edge" />
    </customHeaders>
  </httpProtocol>
</system.webServer>

Użyłem programu Fiddler, aby sprawdzić, czy nagłówek jest rzeczywiście wprowadzany poprawnie.

Rozumiem, że przy tych ustawieniach powinienem być w stanie zastąpić ustawienie przeglądarki „Wyświetlaj witryny intranetowe w widoku zgodności”. Ale w zależności od klienta stwierdziłem, że niektóre z nich nadal będą uruchamiać tryb zgodności. Wydaje się również, że dotyczy to raczej poziomu komputera, a raczej ustawienia grupy zasad, ponieważ uzyskuję różne wyniki, nawet gdy używam tego samego zestawu poświadczeń na różnych klientach.

Wyłączenie pola wyboru Ustawienia widoku zgodności załatwia sprawę. Ale faktycznym celem jest upewnienie się, że aplikacja jest renderowana dokładnie w ten sam sposób, niezależnie od ustawień klienta.

Jakieś myśli i czego mógłbym przegapić? Czy w ogóle można zmusić IE do wyświetlania stron bez uruchamiania trybu Compat?

stukrotne dzięki,

Jaume

PS: strona jest obecnie w fazie rozwoju i oczywiście nie ma jej na liście kompatybilności Microsoftu, ale sprawdziłem też na wszelki wypadek.

Google za „Understanding the Compatibility View List” , niestety silnik SPAM nie pozwala mi na publikowanie więcej niż 2 adresów URL.

JSancho
źródło

Odpowiedzi:

45

Znalazłem problemy z dwoma typowymi sposobami zrobienia tego:

  1. Wykonanie tego z niestandardowymi nagłówkami ( <customHeaders>) w pliku web.config umożliwia różnym wdrożeniom tej samej aplikacji ustawienie tego ustawienia w inny sposób. Widzę to jako jeszcze jedną rzecz, która może pójść nie tak, więc myślę, że lepiej, jeśli aplikacja określa to w kodzie. Ponadto usługi IIS6 nie obsługują tego .

  2. Umieszczenie <meta>tagu HTML na stronie wzorcowej formularzy sieci Web lub stronie układu MVC wydaje się lepsze niż powyższe. Jeśli jednak niektóre strony nie dziedziczą po nich, tag musi zostać zduplikowany, więc istnieje potencjalny problem z konserwacją i niezawodnością.

  3. Ruch sieciowy można zmniejszyć, wysyłając X-UA-Compatiblenagłówek tylko do klientów Internet Explorer.

Dobrze zorganizowane aplikacje

Jeśli Twoja aplikacja ma strukturę, która powoduje, że wszystkie strony ostatecznie dziedziczą z jednej strony głównej, dołącz <meta>znacznik, jak pokazano w innych odpowiedziach .

Starsze aplikacje

W przeciwnym razie myślę, że najlepszym sposobem na to jest automatyczne dodawanie nagłówka HTTP do wszystkich odpowiedzi HTML. Jednym ze sposobów jest użycie 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 wskazuje, że do renderowania strony IE powinien używać swojego najnowszego silnika renderującego (zamiast trybu zgodności).

Wygląda na to, że moduły HTTP są często rejestrowane w pliku web.config, ale to prowadzi nas z powrotem do pierwszego problemu. Jednak można zarejestrować je programowo w Global.asax tak:

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);
    }
}

Należy pamiętać, że ważne jest, aby moduł został utworzony statici nie został utworzony w programie, Initaby na aplikację przypadała tylko jedna instancja. Oczywiście w rzeczywistej aplikacji prawdopodobnie powinien tym zarządzać kontener IoC.

Zalety

  • Przezwycięża problemy przedstawione na początku tej odpowiedzi.

Niedogodności

  • Administratorzy stron internetowych nie mają kontroli nad wartością nagłówka. Może to stanowić problem, jeśli pojawi się nowa wersja programu Internet Explorer i niekorzystnie wpłynie na renderowanie witryny internetowej. Można to jednak obejść, prosząc moduł o odczytanie wartości nagłówka z pliku konfiguracyjnego aplikacji zamiast używania wartości zakodowanej na stałe.
  • Może to wymagać modyfikacji do pracy z ASP.NET MVC.
  • To nie działa w przypadku statycznych stron HTML.
  • Wydaje się, że PreSendRequestHeaderszdarzenie w powyższym kodzie nie jest uruchamiane w usługach IIS6. Nie wymyśliłem jeszcze, jak rozwiązać ten błąd.
Sam
źródło
2
Odpowiedź mogła zająć ponad rok, a aplikacja, nad którą pracowałem, jest teraz przestarzała. Niemniej jednak jest to zdecydowanie najdokładniejsza i najlepiej zbadana odpowiedź, na jaką mogłem liczyć. Dobre rzeczy przychodzą do tych, którzy czekają :) dzięki Sam
JSancho
1
„Powinno to zapewnić spójne wyświetlanie strony w innych przeglądarkach oraz w sposób zgodny ze standardami”. Przepraszam, ale to wcale nie było moje doświadczenie. W tej chwili pracuję z raportem SSRS, który renderuje wszystko źle w IE10, dobrze w Chrome i prawie dobrze w trybie zgodności IE10.
BobRodes,
@BobRodes, myślę, że napisałem to, ponieważ późniejsze wersje IE mają być bardziej zgodne ze standardami, ale tak naprawdę nie mówiłem z doświadczenia, więc dobra uwaga! Właśnie zaktualizowałem odpowiedź, aby usunąć to roszczenie.
Sam
W relacjach z konkurentami Microsoft stosuje koncepcję „objąć, rozszerzyć, wygasić”. Po pierwsze, przyjmij dowolny standard. Następnie „ulepsz” standard za pomocą zastrzeżonych cech i funkcji. Następnie po cichu porzuć obsługę standardu w przyszłych wersjach. Na szczęście mają z tym problem w IE. :)
BobRodes
To zadziałało dla mnie i wypróbowałem kilka różnych rozwiązań, w tym metatag i próbę użycia hacków CSS, aby uwzględnić obszary witryny, które nie były nieprawidłowo renderowane w np.
user609926
39

Zmiana nagłówka na następujący rozwiązuje problem:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />
Gideon
źródło
Musiałem również dodać nagłówek klienta do pliku web.config, aby działał na serwerze Windows 2008
Catch22
17

Aktualizacja: więcej przydatnych informacji Co robi <meta http-equiv = "X-UA-Compatible" content = "IE = edge">?

Może ten adres URL może ci pomóc: Aktywacja trybów przeglądarki za pomocą Doctype

Edycja: Dzisiaj mogliśmy zastąpić widok zgodności: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />

Andrzej
źródło
@Balanivash To była naprawdę dobra lektura, dzięki za link. Artykuł prowadzi mnie do przekonania, że ​​„Tryb zgodności” jest włączony, ponieważ witryna znajduje się w strefie intranetu. Jednak nie występuje to konsekwentnie, na przykład: - win7, IE8, na kliencie -> tryb pełnego standardu - win7, IE8, na innym pudełku z tymi samymi poświadczeniami -> tryb zgodności Aby być po bezpiecznej stronie I ' m także uruchamianie nowych sesji przeglądarki i resetowanie paska narzędzi programisty IE do wartości domyślnych przy każdym teście.
JSancho
Może spróbuj tego: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Andrew
1
Ponadto: jeśli chcesz, aby Twoja aplikacja internetowa mówiła IE8, że naprawdę Ci zaufa, musisz wysłać X-UA-Compatible jako nagłówek HTTP z serwera WWW zamiast metatagu: social.msdn.microsoft.com/Forums/en- US / iewebdevelopment / thread /…
Andrew
2
Właściwie dzisiaj mogliśmy zastąpić widok zgodności z:<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Andrew
2
Dziękujemy za zaktualizowanie odpowiedzi. Myślę, że byłoby lepiej, gdyby twoja odpowiedź była określona, IE=Edgeponieważ pytanie dotyczy wyłączenia trybu zgodności.
Sam
0

W przypadku programistów Node / Express możesz użyć oprogramowania pośredniego i ustawić to za pośrednictwem serwera.

app.use(function(req, res, next) {
  res.setHeader('X-UA-Compatible', 'IE=edge');
  next();
});
mbokil
źródło