Determinare in modo corretto la versione del browser in Internet Explorer 9

Implementare codice dipendente dalla versione del browser e quindi effettuare quella che si chiama "browser detection code" è una modalità di sviluppo assolutamente da evitare, fonte di complicazioni ed errori come ben messo in evidenza in questo post sul blog di IE e come ho anche illustrato in questo post sul mio blog che mostra appunto un esempio dei possibil errori derivanti dall'utilizzo di questa tecnica. Ci sono però casi in cui può essere utile determinare la  versione del browser in uso. Uno dei problemi tipici che mi capita di incontrare relativamente a script sviluppati Internet Explorer è relativo appunto alla parte di codice che viene utilizzata per determinare la versione di IE. In molti casi gli sviluppatori non tengono in considerazione il comportamento di IE9 relativo alle funzionalità di compatibilità e quindi dei differenti document mode che il browser supporta e la modalità con cui si applicano, scrivendo del codice che produce degli errori nel riconoscimento della versione.

Per determinare la versione del browser via JS si utilizzano genericamente le API  navigator.appVersion, navigator.userAgent e navigator.appName ma spesso nel codice che viene scritto , non si tiene conto delle differenti modalità di document mode che Internet Explorer applica, generando quindi degli script che non determinano correttamente la versione del browser. Internet Explorer può infatti, applicare versioni di document mode diverse in base alla struttura del DOCTYPE della pagina e quando viene abilitata la compatibility view, può anche inviare al Web Server uno user agent differente anche nell'header della richiesta HTTP e quindi non soltanto nelle API JS dell'oggetto navigator.

In questo articolo su MSDN trovate un'ottima descrizione dei differenti document mode di Internet Explorer ed in questo post una descrizione del browser mode, del ruolo della compatibility view e del document mode. Determinare il document mode che si applica nell'esecuzione di un a pagina è molto importante non solo per la versione del browser, ma anche perchè le funzionalità di HTML5 in IE9 vengono implementate solo con l'applicazione del document mode IE9 Standard. E' possibile determinare con facilità quale document mode o browser mode viene applicato nella navigazione con IE9 su un sito, utilizzando la developer toolbar. Facendo F12 dopo aver caricato la pagina, comparirà la developer toolbar e tra i menù disponibili troverete anche il browser mode e il document mode che indicano le modalità in quel momento in uso, come potete vedere nell'immagine di seguito:

 

i menù permettono anche di forzare l'applicazione di uno specifico browser mode o document mode. 

Moltissimi script che usano la navigator.appVersion , fanno detect del numero di versione senza tener presente che in caso si applichino document mode precedenti, nella app version viene indicato come primo elemento la versione del browser verso cui il browser sta applicando la compatibiltà, oltre all'indicazione appunto, della versione del browser. Ad esempio nel caso di rendering di una pagina senza DOCTYPE il browser andrà a caricarla in quirks mode e avremo per il valore di navigator.appVersion:

 "5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.4; OfficeLivePatch.1.3; .NET4.0C; .NET4.0E; InfoPath.3; MS-RTC LM 8; Zune 4.7)"

 dove vedete indicato per primo il valore 5.0 proprio perchè si applica il document mode corrispondente appunto alla modalità quirk e viene indicata la versione di IE9 in modalità compatibile.

Per poter determinare correttamente via JavaScript la versione dl browser e distinguerla anche dal document mode in uso nella pagina è consigliabile usare una funzione come quella indicata di seguito, valida anche per le versioni precedenti e che continuerà a funzionare anche per le successive versioni di IE :

function getInternetExplorerVersion()
{
  var rv = -1; 
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}

La funzione ritorna -1 nel caso in cui il browser non è Internet Explorer, altrimenti riporta la versione del browser indipendentemente dal document mode in uso nell'esecuzione della pagina.