Come disattivare forzatamente la modalità di compatibilità di IE dal lato server?


84

In un ambiente controllato dal dominio, sto riscontrando che la modalità di compatibilità viene attivata su alcuni client (winXP / Win7, IE8 / IE9) anche quando forniamo tag X-UA, una definizione! DOCTYPE e una risposta "IE = Edge" intestazioni. Questi client hanno la casella di controllo "Visualizza siti Intranet in visualizzazione compatibilità" selezionata. Che è esattamente ciò che sto cercando di ignorare.

La seguente è la documentazione che ho usato per cercare di capire come IE decide di attivare effettivamente la modalità di compatibilità.

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

I proprietari dei siti hanno sempre il controllo del loro contenuto. I proprietari dei siti possono scegliere di utilizzare il tag X-UA-Compatible per essere assolutamente dichiarativi su come vorrebbero che il loro sito visualizzi e per mappare le pagine in modalità Standard agli standard IE7. L'utilizzo del tag X-UA-Compatible ha la precedenza sulla Visualizzazione Compatibilità sul client.

Google per "Definire la compatibilità dei documenti" , purtroppo il motore SPAM non mi permette di pubblicare più di 2 URL.

Questa è ASP .NETun'app Web e include le seguenti definizioni nella pagina master:

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

e web.config

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

Ho usato Fiddler per verificare che l'intestazione venga effettivamente inserita correttamente.

Da quanto mi risulta, con queste impostazioni dovrei essere in grado di sovrascrivere l'impostazione del browser "Visualizza siti intranet in Visualizzazione Compatibilità". Ma a seconda del client, ho scoperto che alcuni di essi attiveranno comunque la modalità di compatibilità. Sembra anche essere a livello di macchina piuttosto che un'impostazione di gruppo di criteri, poiché ottengo risultati diversi anche quando uso con lo stesso set di credenziali su client diversi.

Disabilitare la casella di controllo Impostazioni Visualizzazione Compatibilità fa il trucco. Ma lo scopo effettivo è assicurarsi che l'app venga visualizzata esattamente nello stesso modo indipendentemente dalle impostazioni del client.

Qualche pensiero e cosa potrei mancare? È possibile forzare IE a eseguire sempre il rendering delle pagine senza attivare la modalità Compat?

Grazie mille,

Jaume

PS: il sito è attualmente in fase di sviluppo e ovviamente non è nell'elenco di compatibilità di Microsoft, ma l'ho anche controllato per ogni evenienza.

Google per "Capire l'elenco di visualizzazione di compatibilità" , purtroppo il motore SPAM non mi consente di pubblicare più di 2 URL.

Risposte:


45

Ho riscontrato problemi con i due modi comuni per farlo:

  1. Farlo con le intestazioni personalizzate ( <customHeaders>) in web.config consente a diverse distribuzioni della stessa applicazione di avere questo set in modo diverso. Lo vedo come un'altra cosa che può andare storta, quindi penso che sia meglio se l'applicazione lo specifica nel codice. Inoltre, IIS6 non lo supporta .

  2. L'inclusione di un <meta>tag HTML in una pagina master di Web Form o in una pagina di layout MVC sembra migliore di quanto sopra. Tuttavia, se alcune pagine non ereditano da queste, il tag deve essere duplicato, quindi c'è un potenziale problema di manutenibilità e affidabilità.

  3. Il traffico di rete potrebbe essere ridotto inviando solo l' X-UA-Compatibleintestazione ai client Internet Explorer.

Applicazioni ben strutturate

Se la tua applicazione è strutturata in modo che tutte le pagine alla fine ereditino da una singola pagina principale, includi il <meta>tag come mostrato nelle altre risposte .

Applicazioni legacy

Altrimenti, penso che il modo migliore per farlo sia aggiungere automaticamente l'intestazione HTTP a tutte le risposte HTML. Un modo per farlo è usare un 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 indica che IE dovrebbe utilizzare il suo motore di rendering più recente (invece della modalità di compatibilità) per eseguire il rendering della pagina.

Sembra che i moduli HTTP siano spesso registrati nel file web.config, ma questo ci riporta al primo problema. Però, puoi registrarli a livello di codice in Global.asax in questo modo:

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

Notare che è importante che il modulo sia statice non istanziato in Initmodo che ci sia solo un'istanza per applicazione. Ovviamente, in un'applicazione del mondo reale un container IoC dovrebbe probabilmente gestirlo.

Vantaggi

  • Supera i problemi delineati all'inizio di questa risposta.

Svantaggi

  • Gli amministratori del sito web non hanno il controllo sul valore dell'intestazione. Questo potrebbe essere un problema se esce una nuova versione di Internet Explorer e influisce negativamente sul rendering del sito web. Tuttavia, questo potrebbe essere superato facendo in modo che il modulo legga il valore dell'intestazione dal file di configurazione dell'applicazione invece di utilizzare un valore hardcoded.
  • Ciò potrebbe richiedere modifiche per funzionare con ASP.NET MVC.
  • Questo non funziona per le pagine HTML statiche.
  • L' PreSendRequestHeadersevento nel codice precedente non sembra attivarsi in IIS6. Non ho ancora capito come risolvere questo bug.

2
Potrebbe essere passato più di un anno prima che la tua risposta arrivasse e l'app effettiva su cui stavo lavorando è ora obsoleta. Tuttavia, questa è sicuramente la risposta più completa e ben studiata che avrei potuto sperare. Le cose buone arrivano a chi
sa

1
"Questo dovrebbe garantire che il rendering della pagina sia coerente con altri browser e in modo conforme agli standard". Mi dispiace, ma questa non è stata per niente la mia esperienza. In questo momento, sto lavorando con un rapporto SSRS che rende tutto sbagliato in IE10, va bene in Chrome e quasi bene in modalità di compatibilità IE10.
BobRodes

@BobRodes, penso di averlo scritto perché le versioni successive di IE dovrebbero essere più conformi agli standard, ma non stavo parlando per esperienza, quindi ottimo punto! Ho appena aggiornato la risposta per rimuovere tale affermazione.
Sam

Microsoft utilizza il concetto di "abbracciare, espandere, estinguere" nelle sue relazioni con i suoi concorrenti. Innanzitutto, abbraccia qualsiasi tipo di standard. Quindi, "migliora" lo standard con caratteristiche e funzioni proprietarie. Quindi, abbandonare silenziosamente il supporto per lo standard nelle versioni future. Fortunatamente, hanno problemi con IE. :)
BobRodes

Questo ha funzionato per me e avevo provato diverse soluzioni tra cui il meta tag e tentando di utilizzare gli hack CSS per tenere conto delle aree del sito che non venivano visualizzate in modo errato in ie.
user609926

39

Cambiare la mia intestazione come segue risolve il problema:

<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge" />

Avevo anche bisogno di aggiungere l'intestazione del cliente al file web.config per farlo funzionare sul server Windows 2008
Catch22

17

Aggiornamento: informazioni più utili Cosa fa <meta http-equiv = "X-UA-Compatible" content = "IE = edge">?

Forse questo URL può aiutarti: Attivare le modalità del browser con Doctype

Modifica: oggi siamo stati in grado di sostituire la visualizzazione della compatibilità con: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />


@Balanivash Questa è stata davvero una buona lettura, grazie per il link. L'articolo mi fa ritenere che la "Modalità compatibilità" sia abilitata perché il sito si trova all'interno della zona intranet. Tuttavia, questo non si verifica in modo coerente, ad esempio: - win7, IE8, su un client -> modalità standard completa - win7, IE8, su una scatola diversa con le stesse credenziali -> modalità compatibilità Per essere al sicuro I ' m anche avviando nuove sessioni del browser e ripristinando la barra degli strumenti per sviluppatori di IE ai valori predefiniti ad ogni test.
JSancho

Forse puoi provare questo: <meta http-equiv="X-UA-Compatible" content="IE=8" />
Andrew

1
Inoltre: se vuoi che la tua applicazione web dica a IE8 di fidarti davvero di te, devi inviare X-UA-Compatible come intestazione HTTP dal tuo server web invece del meta tag: social.msdn.microsoft.com/Forums/en- USA / iewebdevelopment / thread /…
Andrew

2
In realtà oggi siamo stati in grado di ignorare la visualizzazione della compatibilità con: <meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />
Andrew

2
Grazie per aver aggiornato la tua risposta. Penso che sarebbe meglio se la tua risposta specificasse IE=Edgepoiché la domanda riguarda la disabilitazione della modalità di compatibilità.
Sam

0

Per gli sviluppatori Node / Express è possibile utilizzare il middleware e impostarlo tramite il server.

app.use(function(req, res, next) {
  res.setHeader('X-UA-Compatible', 'IE=edge');
  next();
});
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.