Browser sniffing og filtrering

Artiklen fortæller om, hvorledes du finder ud af, hvilken browser, der læser din webside, og hvorledes du anvender oplysningen.

Et klik på knappen herunder fortæller dig, hvilken browser og browserversion, du læser denne side med.

Browserfiltering er noget, en websmed er nødt til at indbygge på websiderne, hvis hun anvender kode, der ikke forstås af alle browsere.

I dag har version 5 og 6 og endnu nyere browsere vundet stor udbredelse, og det er naturligt at bruge de muligheder, der er for bl.a. dynamisk HTML.

Det er derved meget let at komme til at lave websider, der ikke kan læses af alle browsere, eller browsere, der ikke er mainstream, såsom talemaskiner og robotsniffere.

Der kan være flere formål med af lave browsersniffing:

  • at præsentere ældre eller aparte browsere for en eller flere sider, der er tilrettelagt uden brug af den nyere teknologi,
  • at lave kodeforgrening i JavaScript, når forskellige browsere skal bringes til at udføre det samme på forskellige måder, eller
  • Indlæse browserspecifikke stylesheets

2 metoder

Der er to forskellige metoder til at bestemme en browser:

  1. Du kan teste for, om browseren fortolker en bestemt metode, egenskab eller et bestemt objekt, eller
  2. du kan bruge navigator-objektets forskellige egenskaber.

F. eks. vil en kodestump som

if (document.layers) 
  alert("Browseren er Netscape version 4.")

præsentere en alert-boks i Netscape version 4, og ikke i nogen andre browsere. Netscape version 4 er den eneste browser, der fortolker et objekt, der hedder document.layers.

navigator-objektet har en række egenskaber, du kan undersøge for forekomsten af informationer om den aktuelle browser. Det er:

  • navigator.appName, der returnerer browserens navn:
  • navigator.appVersion, der returnerer versionsnummeret:
  • navigator.appCodeName, der returnerer browserens navnekode:
  • navigator.userAgent, der returnerer det meste af det foregående i én tekststreng:

For at få noget ud af disse oplysninger, kan det af og til være nødvendigt at lave noget strengmanipulation på den returnerede tekststreng:

alert(navigator.appVersion.substr(0,4))

- vil f.eks. returnerer de 4 første cifre i den tekststreng, der angiver versionsnummer. Det er i Netscape rent faktisk versionsnummeret. Men ikke i de fleste andre browsere.

I det hele taget er denne måde at afkode navigator-objektet på ikke særlig nem. F.eks. svarer versionsnummeret kun sjældent til, der "står på pakken", navnekoden for de fleste browsere er Mozilla, Opera-browseren er en forklædt Internet Explorer osv.

Derfor er den almindeligste metode ganske enkelt at undersøge den tekststreng, der returneres af f.eks navigator.appVersion eller navigator.userAgent, for forekomsten af de nøgleord, der betyder noget for os. Måden at gøre dette på ser du herunder:

var ie6 
  if (navigator.appVersion.indexOf("MSIE 6") != -1)
    var ie6=true
  else
    var ie6=false

Her undersøges appVersion-tekststrengen for forekomsten af nøgleordene "MSIE 6". Hvis betingelsen evaluerer til forskellig fra null, er det fordi den tekststreng, vi tester for, rent faktisk forekommer, og udfaldet af testen er, at den variable ie6 sættes til true.

"null" er ikke 0, 0 er et tal, mens null er absolut ingenting. Det skrives i JavaScript ofte som anført her, -1.

En komplet browsersniffer

Således bevæbnede kan vi lave os en komplet browsersniffer:

Bortset fra den sidste test er det faktisk denne sniffer, der ligger til grund for den indledende test i denne artikel. Den afspejler de behov, jeg igennem tidens løb har haft for at have adgang til disse variable, og den er en del af den JavaScript fil, jeg indlæser på stort set alle mine websider, og som indeholder såvel snifferen som en del funktioner og andet, jeg meget ofte har brug for.

Et script som dette, der indeholder en lang række betingelsestests, der kun kan have et binært udfald, kan komprimeres en del:

var ver3 = (navigator.appVersion.charAt(0) <= "3") 
  ? 	true : false;
var dom = (document.getElementById) 
  ? 	true : false;
var ie4 = (document.all && !document.getElementById) 
  ? 	true : false;
var ns4 = (document.layers) 
  ? 	true : false;
var ie5 = (navigator.appVersion.indexOf("MSIE 5") != -1)  
  ? 	true : false;
var ie6 = (navigator.appVersion.indexOf("MSIE 6") != -1)  
  ? true : false;
var n6 =  (document.getElementById && !document.all)  
  ?  true : false;
var op7 = (navigator.userAgent.indexOf("Opera 7") != -1) 
  ? true : false
var msie = (document.all) 
  ? true : false;

Omdirigering af gamle browsere

Browsersnifferens allerførste test er et meget godt eksempel på, hvorledes en sådan kan anvendes til omdirigering. Her undersøger jeg, om det allerførste ciffer i appVersion er 3 eller mindre.Hvis det er tilfældet, er der tale om en ganske gammel browser - Netscape 3, Microsoft Internet Explorer 3 eller andre browsere, der med garanti ikke understøtter ret meget af den teknologi, det nuomstunder er ganske almindeligt at anvende på websider.

Jeg gør derfor det, at jeg omdirigerer sådanne browsere

if (ver3||ie4) window.location.href = 
-->  "/web102/res/html/oldbrowser.html";

Den side, jeg omdirigerer til, kan du se ved at klikke her.

Jeg må her krybe til korset og erkende, at jeg ikke selv synes, der er godt nok. Jeg har lagt en del energi i at konstruere websider, der præsenterer sig pænt i visuelt mindre avancerede browsere. Her tænker jeg ikke specielt på gamle browsere, men nok så meget på f.eks. talende browsere, pda'er og den slags. Så det næste skridt ville naturligt være at bruge denne variabel til at vise websiderne uden de stylesheets og JavaScripts, der ville få de ældre browsere til at kløjs.

Som et eksempel på resultatet af en sådan øvelse viser jeg i et nyt browservindue et screenshot af denne webside vist i Netscape 3.

Skil fårene fra bukkene

Den næste test, jeg gennemfører i min browsersniffer er en objekttest, der afslører om browseren forstår objektreferencen document.getElementById. Det er en meget væsentlig test, idet netop denne objektegenskab er uhyre meget anvendt i dynamisk HTML. Den er en del af W3C's anbefalinger for en browsers dokumentobjektmodel (Document Object Model – DOM), og alle moderne browseres DOM omfatter denne egenskab.

Når de to første tests er gennemført, er det ikke mange browsere, der er tilbage. Er der en browser, der ikke fanges af nogen af betingelser, falder denne browser igennem og viser websiden med de eventuelle fejl og mangler, som denne browser opfatter som sådanne.

W3C's validator

Det er en mægtig god idé at validere sine websider i World Wide Web Consortiums validator for både korrekt HTML og for korrekt CSS. http://validator.w3.org.

Også af den årsag er det vigtigt at lave websider, der lægger sig tæt op af standarderne som muligt og validerer korrekt i W3C's validator. Så har du i hvert fald gjort, hvad du kunne.

Kodeforgrening

Kodeforgrening betyder i JavaScript, at dersom browseren er A, udfører scriptet en handling, er browseren B, udføres en anden handling, og er browseren C, udføres en tredie handling. I dynamisk HTML er der uhyre ofte brug for at finde et elements egenskaber – dets højde, bredde, farve, position eller hvad ved jeg. Men før vi kan finde egenskaberne, må vi finde selv elementet – eller objektet, som det oftest hedder i disse sammenhænge. Jeg har gennemgået dette emne i dybden i artiklen Blokvariable i DHTML-sektionen, og nøjes derfor her med at gengive et af eksemplerne herfra:

function findObjekt(objekt) {
var blok;
  if (dom) 
    blok = document.getElementById(objekt).style;
  else 
  if (ie4) 
    blok = document.all[objekt].style;
  else 
  if (ns4) 
    blok = document.layers[objekt];
  return blok;
}

Her ser du kodeforgrening, der tjener til at finde egenskaberne ved et element, der har en id = objekt. Dertil bruger jeg en midlertidig variabel blok. Denne antager de samme værdier i alle de 3 browserkategorier, fordi hver browser undersøger værdierne for blok på den måde, der nu er speciel for denne browser.

Betinget indlæsning af scripts og stylesheets

Herunder ser du to eksempler på betinget indlæsning af scripts og stylesheets.

if (!ver3)
document.write("<script 
-->  src=\"web102\/res\/scripts\/forward.js\"
-->  type=\"text\/javascript\"><\/script>")

Det første eksempel vedrører det JavaScript, der sørger for at håndtere sagerne, hvis du ønsker at anbefale en side på denne site til en ven eller bekendt. Dette script indeholder noget JavaScript, der først er kommet til i version 1.2, dvs. fra og med Netscape 4. Derfor vil Netscape 3 kløjs i scriptet og komme med et par fejlmeldinger til brugeren. Og derfor indlæses scriptet kun i nyere browsere, det vil sige browsere, der ikke opfylder ver3-betingelsen.

if (msie) {
document.write('<link rel="stylesheet" 
-->  type="text/css"
-->  href="/web102/res/style/iefilter.css">\n');
}

Det andet eksempel vedrører et stylesheet, som anvender nogle egenskaber, som kun Internet Explorer kan fortolke. Derfor indlæses dette stylesheet kun i disse browsere.

Denne side er senest opdateret: 25. June, 2008