The Ultimate JavaScript Client Sniffer:
Determining Browser Vendor, Version, And Operating System With JavaScript

When creating a web page, you may wish to account for the possibility that viewers will be using browsers of various versions from various vendors. You may also wish to account for the possibility that certain page elements such as native plug-ins may not be available on all operating systems.

This sample code enables you to detect the browser's vendor, version number, and operating system. It has been tested on Navigator 2, 3, and 4, Internet Explorer 3 and 4, and Opera 3 on Windows 95, Windows NT, the Macintosh, and SunOS5. It is believed to be compatible with all JavaScript-capable browser versions on all platforms. It creates an object called "is" which has properties indicating the browser's vendor, version number, JavaScript version, and operating system.

After you have checked the browser vendor and version, you can dynamically generate optimized HTML markup, and your JavaScript code can conditionally branch to execute JavaScript code optimized for the dynamically generated page or the current browser's vendor or version number.

This tip is useful when developing a page with features not supported by all browsers. For example, users who are using Navigator 4 can view content that includes the new LAYER tag. Other users can view a "non-layers" version of the same file.

As another example, Navigator 4 and Internet Explorer 4 often implement the same Dynamic HTML functionality with different objects and methods. After checking the browser vendor, you can conditionally execute the correct JavaScript code fork for the current browser.

This code has recently gone through a minor update, due to some implementation problems on Internet Explorer 3.x on the Macintosh. If you create an "is" object on IE3 for the Mac, the first time the page is loaded, the code will work fine, however any reloads of the page will cause the browser to crash. To get around this on IE3 for the Mac, we don't create an "is" object; instead, we create a Boolean variable called "isIE3Mac", which is set to true when the page is loaded into Internet Explorer 3 for the Mac OS. One thing to be aware of: when checking the "navigator.appVersion" property, you'll notice on the Windows side that Internet Explorer 3.0 says it's Navigator 2.0, and thus the "navigator.appVersion" property returns a "2." On the Macintosh, Internet Explorer 3.0 says it's Navigator 3.0, and "navigator.appVersion" will return a "3".


DYNAMICALLY GENERATING HTML MARKUP

When optimizing a page for multiple browsers, it is sometimes convenient to check the browser vendor and/or version and then use document.write() statements in <SCRIPT> elements in the page's BODY to dynamically generate HTML markup which is optimized for the current browser. Here is an example of the code necessary to dynamically generate vendor- or version-specific HTML markup. This code uses the "is" object defined by the sample JavaScript code below to check browser vendor and version. Don't forget, however, to first check the boolean variable "isIE3Mac" to see if that's true or not. The reason we check it first is because if "isIE3Mac" is true, then the "is" object doesn't actually exist, and we don't want to script to error out.

<SCRIPT>
<!--
if (!isIE3Mac && is.nav4up) {
  {
   // document.write() statements to create markup for Navigator 4 and later versions
  }
  else if (!isIE3Mac && is.ie4up)
  {
   // document.write() statements to create markup for IE 4 and later versions
  }
  else
  {
   // document.write() statements to create static HTML markup for earlier versions
  }
}
// -->
</SCRIPT>


BROWSER-SPECIFIC JAVASCRIPT CODE FORKS

In your page's core JavaScript functions, you can then have vendor- and version-specific code forks where necessary. These code forks reference objects, properties, methods, and functions which are only available in specific browser versions. The code forks may also reference HTML page elements whose HTML markup is dynamically generated only for certain browser versions.

This code fragment also uses the "is" object, and the "isIE3Mac" boolean defined by the sample JavaScript code below to check browser vendor and version.

if (!isIE3Mac && is.nav4up)
{
   // JavaScript here for Navigator 4 and later 
}
else if (!isIE3Mac && is.ie4up)
{
   // JavaScript here for IE 4 and later
}
else if (!isIE3Mac && (is.nav3 || is.opera))
{
   // JavaScript here for Nav3 and Opera 
}
else 
{
   // JavaScript here for Nav2 and IE 3 
}


JAVASCRIPT CODE TO DETECT BROWSER VENDOR, VERSION, AND OPERATING SYSTEM

Here is the JavaScript code necessary to detect browser vendor, version number, and operating system. This code creates an object called "is" which has properties indicating the browser's vendor, version number, JavaScript version, and operating system.

This code is believed to be compatible with all versions of all JavaScript-capable browsers on all platforms. It has been tested on the following operating systems and browser versions:

// Ultimate client-side JavaScript client sniff.
// (C) Netscape Communications 1998.  Permission granted to reuse and distribute.
// Revised 20 April 98 to add is.nav4up and is.ie4up (see below).

// Everything you always wanted to know about your JavaScript client
// but were afraid to ask ... "Is" is the constructor function for "is" object, 
// which has properties indicating:
// (1) browser vendor:
//     is.nav, is.ie, is.opera
// (2) browser version number:
//     is.major (integer indicating major version number: 2, 3, 4 ...)
//     is.minor (float   indicating full  version number: 2.02, 3.01, 4.04 ...) 
// (3) browser vendor AND major version number
//     is.nav2, is.nav3, is.nav4, is.nav4up, is.ie3, is.ie4, is.ie4up
// (4) JavaScript version number:
//     is.js (float indicating full JavaScript version number: 1, 1.1, 1.2 ...)
// (5) OS platform and version:
//     is.win, is.win16, is.win32, is.win31, is.win95, is.winnt, is.win98
//     is.os2
//     is.mac, is.mac68k, is.macppc
//     is.unix
//        is.sun, is.sun4, is.sun5, is.suni86
//        is.irix, is.irix5, is.irix6 
//        is.hpux, is.hpux9, is.hpux10
//        is.aix, is.aix1, is.aix2, is.aix3, is.aix4  
//        is.linux, is.sco, is.unixware, is.mpras, is.reliant  
//        is.dec, is.sinix, is.freebsd, is.bsd 
//     is.vms
//
// See http://home.kiss.de/~i_thum/JS_tutorial/bstat/navobj.html
// for a detailed list of userAgent strings.
//
// Note: you don't want your Nav4 or IE4 code to "turn off" or
// stop working when Nav5 and IE5 (or later) are released, so
// in conditional code forks, use is.nav4up ("Nav4 or greater")
// and is.ie4up ("IE4 or greater") instead of is.nav4 or is.ie4
// to check version in code which you want to work on future 
// versions.


function Is ()
{   // convert all characters to lowercase to simplify testing
    var agt=navigator.userAgent.toLowerCase()

    // *** BROWSER VERSION ***
    this.major = parseInt(navigator.appVersion)
    this.minor = parseFloat(navigator.appVersion)

    this.nav  = ((agt.indexOf('mozilla')!=-1) && ((agt.indexOf('spoofer')==-1)
                && (agt.indexOf('compatible') == -1)))
    this.nav2 = (this.nav && (this.major == 2))
    this.nav3 = (this.nav && (this.major == 3))
    this.nav4 = (this.nav && (this.major == 4))
    this.nav4up = this.nav && (this.major>= 4)
    this.navonly      = (this.nav && (agt.indexOf(";nav") != -1))

    this.ie   = (agt.indexOf("msie") != -1)
    this.ie3  = (this.ie && (this.major == 2))
    this.ie4  = (this.ie && (this.major == 4))
    this.ie4up  = this.ie  && (this.major>= 4)

    this.opera = (agt.indexOf("opera") != -1)
     
    // *** JAVASCRIPT VERSION CHECK *** 
    // Useful to workaround Nav3 bug in which Nav3 
    // loads <SCRIPT LANGUAGE="JavaScript1.2">.
    if (this.nav2 || this.ie3) this.js = 1.0
    else if (this.nav3 || this.opera) this.js = 1.1
    else if (this.nav4 || this.ie4) this.js = 1.2
    // NOTE: In the future, update this code when newer versions of JS 
    // are released. For now, we try to provide some upward compatibility 
    // so that future versions of Nav and IE will show they are at 
    // *least* JS 1.2 capable. Always check for JS version compatibility 
    // with> or>=.
    else if ((this.nav && (this.minor> 4.05)) || (this.ie && (this.major> 4))) 
         this.js = 1.2
    else this.js = 0.0 // HACK: always check for JS version with> or>=

    // *** PLATFORM ***
    this.win   = ( (agt.indexOf("win")!=-1) || (agt.indexOf("16bit")!=-1) )
    // NOTE: On Opera 3.0, the userAgent string includes "Windows 95/NT4" on all
    //        Win32, so you can't distinguish between Win95 and WinNT.
    this.win95 = ((agt.indexOf("win95")!=-1) || (agt.indexOf("windows 95")!=-1))

    // is this a 16 bit compiled version?
    this.win16 = ((agt.indexOf("win16")!=-1)
               || (agt.indexOf("16bit")!=-1) || (agt.indexOf("windows 3.1")!=-1)
               || (agt.indexOf("windows 16-bit")!=-1) )  

    this.win31 = (agt.indexOf("windows 3.1")!=-1) || (agt.indexOf("win16")!=-1) ||
                 (agt.indexOf("windows 16-bit")!=-1)

    // NOTE: Reliable detection of Win98 may not be possible. It appears that:
    //       - On Nav 4.x and before you'll get plain "Windows" in userAgent.
    //       - On Mercury client, the 32-bit version will return "Win98", but
    //         the 16-bit version running on Win98 will still return "Win95".
    this.win98 = ((agt.indexOf("win98")!=-1)||(agt.indexOf("windows 98")!=-1))
    this.winnt = ((agt.indexOf("winnt")!=-1)||(agt.indexOf("windows nt")!=-1))
    this.win32 = this.win95 || this.winnt || this.win98 || 
                 ((this.major>= 4) && (navigator.platform == "Win32")) ||
                 (agt.indexOf("win32")!=-1) || (agt.indexOf("32bit")!=-1)

    this.os2   = (agt.indexOf("os/2")!=-1) 
                 || (navigator.appVersion.indexOf("OS/2")!=-1)  
                 || (agt.indexOf("ibm-webexplorer")!=-1)

    this.mac    = (agt.indexOf("mac")!=-1)
    this.mac68k = this.mac && ((agt.indexOf("68k")!=-1) || 
                               (agt.indexOf("68000")!=-1))
    this.macppc = this.mac && ((agt.indexOf("ppc")!=-1) || 
                               (agt.indexOf("powerpc")!=-1))

    this.sun   = (agt.indexOf("sunos")!=-1)
    this.sun4  = (agt.indexOf("sunos 4")!=-1)
    this.sun5  = (agt.indexOf("sunos 5")!=-1)
    this.suni86= this.sun && (agt.indexOf("i86")!=-1)
    this.irix  = (agt.indexOf("irix") !=-1)    // SGI
    this.irix5 = (agt.indexOf("irix 5") !=-1)
    this.irix6 = ((agt.indexOf("irix 6") !=-1) || (agt.indexOf("irix6") !=-1))
    this.hpux  = (agt.indexOf("hp-ux")!=-1)
    this.hpux9 = this.hpux && (agt.indexOf("09.")!=-1)
    this.hpux10= this.hpux && (agt.indexOf("10.")!=-1)
    this.aix   = (agt.indexOf("aix")  !=-1)      // IBM
    this.aix1  = (agt.indexOf("aix 1")  !=-1)    
    this.aix2  = (agt.indexOf("aix 2")  !=-1)    
    this.aix3  = (agt.indexOf("aix 3")  !=-1)    
    this.aix4  = (agt.indexOf("aix 4")  !=-1)    
    this.linux = (agt.indexOf("inux")!=-1)
    this.sco   = (agt.indexOf("sco")!=-1) || (agt.indexOf("unix_sv")!=-1)
    this.unixware = (agt.indexOf("unix_system_v")!=-1) 
    this.mpras    = (agt.indexOf("ncr")!=-1) 
    this.reliant  = (agt.indexOf("reliantunix")!=-1)
    this.dec   = (agt.indexOf("dec")!=-1) || (agt.indexOf("osf1")!=-1) 
           || (agt.indexOf("dec_alpha")!=-1) || (agt.indexOf("alphaserver")!=-1) 
           || (agt.indexOf("ultrix")!=-1) || (agt.indexOf("alphastation")!=-1) 
    this.sinix = (agt.indexOf("sinix")!=-1)
    this.freebsd = (agt.indexOf("freebsd")!=-1)
    this.bsd = (agt.indexOf("bsd")!=-1)
    this.unix  = (agt.indexOf("x11")!=-1) || this.sun || this.irix || this.hpux || 
                 this.sco ||this.unixware || this.mpras || this.reliant || 
                 this.dec || this.sinix || this.aix || this.linux || this.freebsd

    this.vms   = (agt.indexOf("vax")!=-1) || (agt.indexOf("openvms")!=-1)
}

var is;
var isIE3Mac = false;
// this section is designed specifically for IE3 for the Mac 

if ((navigator.appVersion.indexOf("Mac")!=-1) && (navigator.userAgent.indexOf("MSIE")!=-1) && (parseInt(navigator.appVersion)==3))
       isIE3Mac = true;

else 

       is = new Is(); 


PROFILE OF YOUR BROWSER

Here are the results of running that JavaScript code on the browser you are using. The below text has been dynamically generated after checking your browser vendor, version, and operating system from JavaScript.

Basic Data

Version Number

Browser Version

JavaScript Version

OS


ADDITIONAL READING
JavaScript Known Bug List
Sample Code Area
Books
Articles
JavaScript Course
Other JavaScript Resources
JavaScript Language Spec
JavaScript Guide
What's New in JavaScript for Navigator 4.0
JavaScript Scripting Tools


VIEW SOURCE ARTICLES
Beyond Data Basics: Writing JavaScript Database Applications, Part 1
Beyond Data Basics: Writing JavaScript Database Applications, Part 2
JavaScript Date Object Techniques
Scripting Layer Effects and Transitions
Detecting a JavaScript Client
Bringing Images to Life with JavaScript


MEMBERS RESOURCES
JavaScript Newsgroup
JavaScript FAQ


DevEdge Online FAQ
Developer Response Center
Join DevEdge Program
Copyright © 1998 Netscape Communications Corporation.
This site powered by: Netscape Enterprise Server and Netscape Compass Server.