Ako rozpoznať pomocou JavaScriptu veľké množstvo prehliadačov

19. července 2001

Aj keď sa zdá, že v dnešnej dobe sa používa iba jeden prehliadač, sú situácie, keď je dobré vedieť a poznať, s akým prehliadačom máte tu česť. Hlavne v dnešnej dobe, keď každý z prehliadačov si po svojom „vysvetľuje“ štandardy, prípadne si zavádza vlastné riešenia. Potom máte iba dve možnosti: buď upraviť svoj kód tak, aby bol čo najjednoduchší a vyhovoval všetkým (väčšine) prehliadačom, alebo môžete rozpoznať prehliadač a podľa toho optimalizovať kód pre každý prehliadač zvlášť. Dnes sa budem zaoberať druhou možnosťou. Uznávam, že je zložitejšia, ale zase na druhej strane výsledok stojí za to.

V dnešnej dobe existuje viacero prehliadačov s niekoľkými verziami. Skript na ich rozpoznávanie je napísaný v JavaScripte, teda umožňuje rozoznať iba prehliadače podporujúce JavaScript. Podrobne však rozozná väčšinu dnes používaných verzií:

  • Microsoft Internet Explorer 3.x až 5.x a novší
  • Netscape Navigator/Communicator 3.x, až 6.x a novší
  • Mozilla 0.x.x a novší
  • Opera 4.x a novší

Malá ukážka skriptu:

Na pochopenie skriptu nemusíte mať hlboké znalosti JavaScriptu, postačia vám iba základné. Skript pracuje v princípe tak, že existujú dve globálne premenné, SkutocneMeno, SkutocnaVerzia a jedna funkcia, AkyBrowser(), ktorá naplní tieto dve premenné menom prehliadača a jeho verziou. Funkcia umožňuje ďalej spracovávať premenné, napríklad výpis prehliadača, ako môžete vidieť v ukážke, alebo, čo budete asi najviac používať, na základe obsahu premenných presmerovať na stránku s optimalizovaným kódom pre daný prehliadač. Skript nie je napísaný priamo v html kóde danej stránky, ale je uložený ako samostatný súbor, ktorý si môžete stiahnuť tu – akybr.js. Spôsob zapracovania do stránky je ukázaný v ukážke, čiže stačí ak si pozriete zdrojový kód ukážky. Toto riešenie som zvolil preto, lebo predpokladám, že skript bude často používaný a pripadá mi flexibilnejšie. Ale nie je vôbec problém vložiť tento skript priamo do html kódu – záleží iba na vás.

Toľko úvodom a teraz prejdem k detailnému popisu práce skriptu. Najprv načrtnem postup a popíšem použité metódy a potom popíšem ich priame „nasadenie“ v praxi.

Na rozpoznanie prehliadača a jeho verzie postačia vlastnosti objektu Browser a metódy objektu String jazyku JavaScript.

Objekt Browser obsahuje štyri vlastnosti, pomocou ktorých je možné získať informácie o prehliadači. Sú to vlastnosti appName, appVersion, userAgent a appCodeName. V praxi bude stačiť použiť iba prvé tri vlastnosti. Uvediem ich krátky popis:

  • appName – udáva meno prehliadača
  • appVersion – udáva verziu prehliadača + ďalšie vlastnosti, ako sú platforma, na ktorej prehliadač beží apod.
  • userAgent – sú to informácie posielané od klienta k serveru pomocou protokolu HTTP, obsahujúce okrem iného aj meno a verziu prehliadača

Takto by sa mohlo zdať, že úloha je jednoduchá, a že nie je o čom písať. Avšak ako sa v živote často stáva, zdanie klame. Výstupom jednotlivých vlastností je reťazec obsahujúci dané informácie. Celý problém a určitá zložitosť spočíva v tom, že treba z toho reťazca plného informácií vybrať tie správne a na ich základe určiť verziu a typ prehliadača. Je síce pekné, že vlastnosťou appName dostanem meno prehliadača – smutnejšie je však to, že menom Netscape sa hlásia všetky Netscape Navigator-y/Communicator-y a tiež aj všetky Mozilly. Preto je nutné zistiť si všetky tieto informácie a z nich povyberať iba tie, ktoré potrebujem. Na „vybratie“ a zistenie informácií slúžia metódy objektu String (reťazec), lebo ako som už spomínal výstupom vlastností objektu Navigator je reťazec. Pre prácu s reťazcami budem používať tieto metódy:

  • indexOf(hľadaný reťazec, odkiaľ) – vyhľadá znak, alebo reťazec v reťazci; hľadaný reťazec – je to znak, alebo reťazec, ktorý sa hľadá v inom reťazci a ak sa nájde, tak vráti hodnotu (index) jeho pozície; v prípade ak sa hľadaný reťazec/znak nenájde vráti sa hodnota -1; odkiaľ – ak nie je zadané hľadá sa od začiatku reťazca, ak je, hľadá sa od pozície odkiaľ,
  • lastIndexOf – to isté ako indexOf, len sa začína od konca prehľadávaného reťazca; staršie ako štvorkové verzie prehliadačov Netscape a Internet Explorer ho nepoznajú,

  • substring(indexA, indexB) – vráti iba časť reťazca (podreťazec) z iného reťazca; indexA – začiatočný znak; indexB – koncový znak podreťazca,
  • length – zistí dĺžku reťazca.

Tieto všetky vlastnosti a metódy stačia na to, aby sa dala rozoznať verzia a typ prehliadača.

Teraz už konečne popíšem skript. Pôjdem riadok za riadkom, ale pre istou bude lepšie si pozrieť aj celý skript. Najskôr si definujem dve globálne premenné SkutocneMeno a SkutocnaVerzia.

var SkutocneMeno, SkutocnaVerzia;

V týchto premenných bude nakoniec uložený reťazec označujúci meno prehliadača a jeho verziu. Aj keď verzia je číslo, bude vo forme reťazca.

Ďalej skript obsahuje iba jednu funkciu AkyBrowser(). Táto funkcia naplní predchádzajúce globálne premenné (SkutocneMeno a SkutocnaVerzia). Vo funkcií som si definoval lokálne premenné a zároveň som niektorým hneď priradil hodnotu:

function AkyBrowser()
{
    var MenoBrowsera = navigator.appName,
          VerziaBrowsera = navigator.appVersion,
          Agent = navigator.userAgent,
          StartStr, EndStr;
  • MenoBrowsera – je to reťazec obsahujúci vlastnosť získanú pomocou navigator.appName,
  • VerziaBrowsera – je to reťazec obsahujúci vlastnosť získanú pomocou navigator.appVersion,
  • Agent – je to reťazec obsahujúci vlastnosť získanú pomocou navigator.userAgent,
  • StartStr, EndStr – používam ich ako označenie začiatočného a konečného znaku pri metóde substring().

Čiže akonáhle sa zavolá funkcia AkyBrowser(), tak do vyššie uvedených premenných sa priradia informácie o aktuálnom prehliadači. Ďalej postupujem tak, že podľa ďalej popísaných kritérií určím prehliadač a jeho verziu. Pri každom type prehliadača uvediem aj výpis reťazcov MenoBrowsera, VerziaBrowsera a Agent.

Najprv teda určím či náhodou nemám dočinenia s Microsoft Internet Explorer-om. Uvediem tu typický výpis pre tento prehliadač:

MenoBrowsera = „Microsoft Internet Explorer“
VerziaBrowsera = „4.0 (compatible; MSIE 5.5; Windows 98)“
Agent = „Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)“

Internet Explorer, resp. jeho meno, sa dá vždy identifikovať cez vlastnosť navigator.appName, čiže v mojom skripte cez premennú MenoBrowsera. Zistiť verziu Internet Explorer-u je možné tak, že v premennej (vlastne reťazci) VerziaBrowsera nájdem poradie znakov „MSIE“ a hneď za ním až po najbližšiu bodkočiarku je uvedené číslo verzie. Teda:

    if(MenoBrowsera == „Microsoft Internet Explorer“)
    {
        SkutocneMeno = MenoBrowsera;
        StartStr = VerziaBrowsera.indexOf(„MSIE“) + 5;
        EndStr = VerziaBrowsera.indexOf(„;“, StartStr);
        SkutocnaVerzia = VerziaBrowsera.substring(StartStr, EndStr);

Premennej SkutocneMeno priradím MenoBrowsera – lebo to presne vystihuje meno prehliadača. Premenná StartStr obsahuje číslo, ktoré udáva na ktorom mieste v reťazci VerziaBrowsera začína reťazec „MSIE“, resp. jeho prvé písmeno „M“. K tomuto číslu potom pripočítam 5, je to počet písmen MSIE plus jedna medzera a dostanem začiatočnú pozíciu (index) čísla verzie prehliadača. Ďalej zisťujem, kde končí číslo verzie prehliadača. To sa nachádza v premennej EndStr, kde hľadám bodkočiarku, ale všimnite si, že až od výskytu reťazca „MSIE“. Ak by som v riadku VerziaBrowsera.indexOf(„;“, StartStr); nedal StartStr, tak by sa reťazec VerziaBrowsera prehľadával od začiatku a našla by sa prvá bodkočiarka za slovom „compatible“, čo samozrejme nechcem. Ostáva už iba premennej SkutocnaVerzia priradiť správnu časť reťazca VerziaBrowsera a to zaistím použitím metódy VerziaBrowsera.substring s parametrami StartStr a EndStr, ktorá priradí premennej SkutocnaVerzia reťazec, v tomto prípade „5.5“, resp. celé číslo verzie.

S Internet Explorerom by som mohol byť už hotový, ale kvôli prehliadaču Opera to nie je ešte možné. Prehliadač Opera totiž umožňuje aby si užívateľ nastavil, že Opera sa bude identifikovať nie ako Opera, ale ako napr. Internet Explorer 5.0 alebo ako Mozilla rôznych verzií. Teraz ma bude zaujímať ako vyzerajú premenné keď sa Opera identifikuje ako Internet Explorer:

MenoBrowsera = “ Microsoft Internet Explorer“
VerziaBrowsera = “ 4.0 (compatible; MSIE 5.0; Windows 98)“
Agent = „Mozilla/4.0 (compatible; MSIE 5.0; Windows 98) Opera 5.0 [en]“

Všimnite si, že je to veľmi, veľmi podobné ako ozajstný Internet Explorer. Jediný rozdiel je v reťazci Agent, kde sa predsa len nachádza zmienka o Skutočnom prehliadači a jeho verzii. Preto musím do skriptu napísať kód, ktorý sa postará o kontrolu, či náhodou Internet Explorer nie je „prešibaná“ Opera?:o):

        if(Agent.indexOf(„Opera“) >= 0)
        {
            var pomStr = SkutocneMeno + “ “ + SkutocnaVerzia;
            StartStr = Agent.indexOf(„Opera“) + 6;
            EndStr = Agent.indexOf(„[„, StartStr)-2;
            SkutocnaVerzia = Agent.substring(StartStr, EndStr) + „, identifikujúca sa ako “ + pomStr;
            SkutocneMeno = Agent.substring(StartStr-6, StartStr);
            }
        }

Ak sa teda v reťazci premennej Agent nachádza podreťazec „Opera“ (ak by sa nenachádzal, tak metóda indexOf by vrátila číslo -1), treba urobiť potrebné korekcie. Zaviedol som si pomocnú premennú pomStr, kam priradím doteraz zistené meno a verziu prehliadača (v tomto prípade to bude vždy nejaký Internet Explorer x.x). Znova obdobným spôsobom zistím verziu prehliadača opery. Pri EndStr musím odčítať -2 preto, lebo v skutočnosti sú medzi koncom čísla verzie a hranatou zátvorkou dve medzery, avšak HTML zobrazí iba jednu! A ku skutočnej verzii priradím ešte reťazec pomStr, aby som presne zistil, ako sa Opera identifikuje, ale v podstate je to iba pre efekt. No a nakoniec ešte do premennej SkutocneMeno priradím reťazec „Opera“, ktorý dostanem tiež pomocou hrátok s číslami v premenných StartStr a EndStr. Týmto je ukončená identifikácia prehliadača Internet Explorer.

Ak prehliadač nie je Internet Explorer alebo Opera tváriaca sa ako Internet Explorer, tak ďalej zisťujem, či prehliadač nie je tentoraz Opera, ktorá sa priznáva k svojmu pôvodu. Výpis premenných v takomto prípade vyzerá takto:

MenoBrowsera = „Opera“
VerziaBrowsera = “ 5.0 (Windows 98; U)“
Agent = „Opera/5.0 (Windows 98; U) [en]“

Kód skriptu pre rozpoznanie vyzerá zase takto:

        else if(MenoBrowsera == „Opera“)
        {
            SkutocneMeno = MenoBrowsera;
            StartStr = 0;
            EndStr = VerziaBrowsera.indexOf(„(„);
            SkutocnaVerzia = VerziaBrowsera.substring(StartStr, EndStr);
        }

Pri Opere to mám jednoduché. Skutočné meno sa zhoduje s premennou MenoBrowsera a verziu zistím jednoducho z premennej VerziaBrowsera. Počiatočný index (StartStr) je 0, lebo číslo začína hneď na začiatku reťazca. Koncový index je o jeden menej ako prvá ľavá zátvorka. No a potom získať skutočnú verziu nie je už žiaden problém.

Ostáva už iba rozpoznať verzie prehliadača Netscape a Mozilla, čo bude trošku zložitejšie, vzhľadom na to, že premenná MenoBrowsera obsahuje vždy a iba reťazec „Netscape“. Začnem teda tým, že zisťujem, či premenná MenoBrowsera obsahuje reťazec „Netscape“:

    else if(MenoBrowsera == „Netscape“)
    {

Zatiaľ je to jednoduché :). Ak som už zistil, že mám dočinenia s nejakým Netscape-om, tak najprv zisťujem, či to náhodou nie je Netscape verzie 6.x. Výpis premenných pri verzií 6.x vyzerá takto:

MenoBrowsera = „Netscape“
VerziaBrowsera = „5.0 (Windows; en-US)“
Agent = „Mozilla/5.0 (Windows; U; Win98; en-US; m18) Gecko/20010131 Netscape6/6.01“

Všimnite si, ak sa tento výpis porovná s výpisom s Mozillou uvedeným neskôr, tak rozdiel existuje iba v reťazci premennej Agent. Preto sa zameriam iba na túto premennú:

        if(Agent.indexOf(„Netscape“) >= 0)
        {
            SkutocneMeno = MenoBrowsera;
            StartStr = Agent.lastIndexOf(„/“)+1;
            EndStr = Agent.length;
            SkutocnaVerzia = Agent.substring(StartStr, EndStr);
        }

Ak premenná Agent obsahuje reťazec „Netscape“ je to určite prehliadač Netscape verzie 6.x. Čiže znova mi MenoBrowsera vyhovuje a ostáva mi len určiť jeho verziu. Tá sa nachádza za posledným lomítkom v reťazci premennej Agent. Keďže viem, že je to Netscape verzie 6.x, môžem použiť metódu lastIndexOf, aby som si zjednodušil prácu. Koniec verzie, je zároveň koncom celého reťazca Agent, čiže použijem na uľahčenie metódu Agent.length.

Netscape 6 je za mnou a idem zistiť, či sa nejedná o našu starú, ale známu „prešibanú“ Operu, identifikujúcu sa tento krát ako Mozilla 3.x, 4.x, alebo 5.x. Výpis je nasledovný:

MenoBrowsera = “ Netscape“
VerziaBrowsera = “ 5.0 (Windows 98; U)“
Agent = “ Mozilla/5.0 (Windows 98; U) Opera 5.0 [en]“

Tak ako keď sa opera „tvárila“ ako Internet Explorer aj teraz ju „prezrádza“ posledný reťazec, resp. premenná Agent, resp. podreťazec „Opera“.

        else if(Agent.indexOf(„Opera“) >= 0)
        {
            StartStr = Agent.indexOf(„Opera“) + 6;
            EndStr = Agent.indexOf(„[„, StartStr)-2;
            SkutocnaVerzia = Agent.substring(StartStr, EndStr);
            SkutocneMeno = Agent.substring(StartStr-6, StartStr);
            StartStr = Agent.indexOf(„/“);
            EndStr = Agent.indexOf(„(„, StartStr);
            var pomStr = „, indetifikujúca sa ako “ + Agent.substring(0, StartStr) + “ “ + Agent.substring(StartStr+1, EndStr);
            SkutocnaVerzia = SkutocnaVerzia + pomStr;
        }

Čiže postup je obdobný, ba až rovnaký, ako pri prehliadači Internet Explorer, resp. Opera identifikujúcej sa ako Internet Explorer. Najprv zisťujem verziu a meno Opery a potom do premennej pomStr priradím meno a verziu akou sa Opera identifikuje. Nakoniec k premennej SkutocnaVerzia priradím aj toto meno a verziu. Samozrejme, tak ako v minulom prípade, aj tu je možné vynechať druhú identifikáciu a uspokojiť sa iba s informáciou o tom, že je to Opera.

Ďalej budem identifikovať Mozillu ľubovoľnej verzie. Tá sa oproti prehliadaču Netscape 6 a nižších verzií odlišuje tým, že v premennej Agent nemá podreťazec „Netscape“ ani „Opera“ a navyše obsahuje v reťazci premennej Agent podreťazec „rv:“. Výpis je:

Meno browsera: Netscape
Verzia browsera: 5.0 (Windows; en-US)
User Agent: Mozilla/5.0 (Windows; U; Win98; en-US; rv:0.9.2) Gecko/20010628

Všimnite si, ako som už spomínal, že je to skoro na nerozoznanie od Netscape 6.

        else if(Agent.indexOf(„rv:“) >= 0)
        {
            SkutocneMeno = „Mozilla“;
            StartStr = Agent.indexOf(„rv:“) + 3;
            EndStr = Agent.indexOf(„)“);
            SkutocnaVerzia = Agent.substring(StartStr, EndStr);
        }

Ak teda Agent obsahuje podreťazec „rv:“, tak do premennej SkutocneMeno priradím reťazec „Mozilla“. Podreťazec „rv:“ zároveň označuje začiatok označenia verzie a následujúca pravá zátvorka jeho koniec.

Ostáva mi už iba rozpoznať staršie verzie prehliadača Netscape – Netscape Navigator/Communicator a Netscape 3.x. Najprv sa pustím do verzie 4. Tu sa dá rozlíšiť, či sa ide o verziu Netscape Navigator 4.x, alebo Netscape Communicator 4.x. Uvediem výpis Navigator-u a aj Communicator-u:

Netscape Navigator 4.x:

MenoBrowsera = “ Netscape“
VerziaBrowsera = “ 4.08 [en] (Win98; U ;Nav)“
Agent = “ Mozilla/4.08 [en] (Win98; U ;Nav)“

Netscape Communicator 4.x:

MenoBrowsera = “ Netscape“
VerziaBrowsera = “ 4.77 [en] (Win98; U)“
Agent = “ Mozilla/4.77 [en] (Win98; U)“

Ako je možné vidieť, líšia sa iba podreťazcom „Nav“ v premennej Agent, alebo VerziaBrowsera. Podľa toho ich aj budem od seba rozlišovať:

        else if((Agent.indexOf(„Nav“) >= 0) || (VerziaBrowsera.substring(0, 1) == „4“))
        {
            if(Agent.indexOf(„Nav“) >=0)
                SkutocneMeno = MenoBrowsera + “ Navigator“;
            else
                SkutocneMeno = MenoBrowsera + “ Communicator“;
            StartStr = 0;
            EndStr = VerziaBrowsera.indexOf(„[„);
            SkutocnaVerzia = VerziaBrowsera.substring(StartStr, EndStr);
        }

Či sa jedná o verziu 4 zistím tak, že buď premenná Agent obsahuje už spomínaný podreťazec „Nav“, alebo premenná VerziaBrowsera obsahuje podreťazec „4“. Podľa toho aj priradím premennej SkutocneMeno reťazec „Navigator“ alebo „Communicator“. Číslo verzie zistím z premennej VerziaBrowsera, vám teraz už určite známym spôsobom.

Ešte mi ostáva verzia Netscape 3.x. Tú rozoznám podobne ako verziu 4.x podľa prvého znaku v premennej VerziaBrowsera. Výpis je:

MenoBrowsera = “ Netscape“
VerziaBrowsera = “ 3.04Gold (Win95; I)“
Agent = “ Mozilla/3.04Gold (Win95; I)“

Teda:

        else if(VerziaBrowsera.substring(0, 1) == „3“)
        {
            SkutocneMeno = MenoBrowsera + “ Navigator“;
            StartStr = 0;
            EndStr = VerziaBrowsera.indexOf(„(„);
            SkutocnaVerzia = VerziaBrowsera.substring(StartStr, EndStr);
        }

Začiatok indexu verzie je opäť 0 a koniec je ohraničený ľavou zátvorkou. Ešte mi ostáva nejaká iná verzia prehliadača Netscape Navigator. Tu sa spoľahnem iba na premennú MenoBrowsera a VerziaBrowsera a na to, že verzia bude ohraničená ľavou zátvorkou.

        else
        {
            SkutocneMeno = MenoBrowsera;
            StartStr = 0;
            EndStr = VerziaBrowsera.indexOf(„(„);
            SkutocnaVerzia = VerziaBrowsera.substring(StartStr, EndStr);
        }
    }

Pre istotu ešte počítam s nejakým iným prehliadačom, ktorý nespadá medzi tie, ktoré som vyššie popísal a tu sa naozaj spoľahnem iba na základné informácie získané pomocou vlastností navigator.appName a navigator.appVersion.

    else
    {
        SkutocneMeno = MenoBrowsera;
        SkutocnaVerzia = VerziaBrowsera;
    }
} //koniec funkcie

Tak a je tu koniec. V podstate ste dostali návod ako rozoznať jednotlivé prehliadače medzi sebou a nie je problém upraviť si tento skript tak aby vám lepšie vyhovoval, resp. môžete kľudne použiť iný algoritmus pri získavaní týchto údajov. Ďakujem za pozornosť a teším sa na vás pri nejakých ďalších článkoch.

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *