JavaScript’s Navigator object provides properties that indicate the type of browser and other useful information about the user accessing the page. The most commonly used Navigator properties having to do with the browser version are detailed in Table 17-1. Most of these properties relate to a piece of the user-agent string that is automatically transmitted to the server by the browser with every request. Note that many of these properties work only in one particular browser type, so developers should stick with the commonly supported appName, appVersion, and userAgent properties.
Property Name |
Description |
Example Value |
Compatibility |
---|---|---|---|
appCodeName |
Contains the code name of the browser in use |
Mozilla |
All JS-aware browsers, but will generally return only “Mozilla” for historical reasons. |
appMinorVersion |
The sub-version or upgrades of the browser |
;SP1; |
Internet Explorer only. |
appName |
The official name of the browser |
Microsoft Internet Explorer |
All JS-aware browsers, but may not be accurate because Opera and WebTV spoof the value. |
appVersion |
Contains the version of the browser |
5.0 (Windows; en-US) |
All JS-aware browsers, but may contain more information than version, including platform and language type. |
userAgent |
The complete user-agent value transmitted to the server by the browser |
Mozilla/5.0 (Windows; U; WinNT4.0; en-US; m18) Gecko/20010131 Netscape6/6.01 |
All JS-aware browsers. There is some question if the browser may spoof a value that is different from what JavaScript reports. |
vendor |
Indicates the browser vendor |
Netscape6 |
Netscape 6 and greater only. |
VendorSub |
Indicates the version number of the browser |
6.01 |
Netscape 6 and greater only. |
The examination of user-agents for typical browsers reveals a variety of cryptic numbers and abbreviations. Most of these values are rarely used. Rather, the “important” fields, such as major version number and operating system, are extracted and the rest is ignored. For example, when detecting Netscape 6, the important substring is “Netscape 6.” Developers usually do not care which particular versions of the browser and rendering engines (for instance, Mozilla or Gecko) went into the release.
The following simple script shows the basic use of the Navigator properties for browser detection. It simply prints the browser name and version values onscreen. An example of the script’s rendering in some common browsers is shown in Figure 17-1.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html xmlns="http://www.w3.org/1999/xhtml">> <<head>> <<title>>Browser Detect Example<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<script type="text/javascript">> <<!-- var browserName = navigator.appName; var browserVersion = parseFloat(navigator.appVersion); var userAgent = navigator.userAgent; document.write("Your browser's user-agent string = "+userAgent + "<<br />>"); document.write("Your browser name = "+ browserName+"<<br />>"); document.write("Your browser version = "+browserVersion+"<<br />>"); // -->> <</script>> <<noscript>> Sorry, I can't detect your browser without JavaScript. <</noscript>> <</body>> <</html>>
Notice already from Figure 17-1 that the browserVersion and even browserName appears to misreport in some browsers like Opera, despite the fact that the userAgent values are quite different. What we are seeing here is the downside of relying on anything but the user agent string. Browsers purposefully try to look somewhat similar so they are not locked out of sites. You need to get deep into the navigator.userAgent value to make sure you know what you are looking at. A slightly improved version shown here is capable of detecting the likely browsers you will encounter.
<<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">> <<html xmlns="http://www.w3.org/1999/xhtml">> <<head>> <<title>>Browser Detect Example 2<</title>> <<meta http-equiv="content-type" content="text/html; charset=utf-8" />> <</head>> <<body>> <<script type="text/javascript">> <<!-- var userAgent = navigator.userAgent; var opera = (userAgent.indexOf('Opera') != -1); var ie = (userAgent.indexOf('MSIE') != -1); var gecko = (userAgent.indexOf('Gecko') != -1); var oldnetscape = (userAgent.indexOf('Mozilla') != -1); if (opera) document.write("Opera based browser"); else if (gecko) document.write("Mozilla based browser"); else if (ie) document.write("IE based browser"); else if (oldnetscape) document.write("Older Netscape based browser"); else document.write("Unknown browser"); // -->> <</script>> <<noscript>> Sorry, I can't detect your browser without JavaScript. <</noscript>> <</body>> <</html>>
Using a script like the one just given, it is possible to create conditional markup based upon the browser hitting the page. For example, consider the code here, which outputs some browser-specific markup according to the particular browser in use:
if (ie && !opera) document.write("<<marquee>>Some IE specific markup!<</marquee>>"); else if (oldnetscape) document.write("<<blink>>Netscape specific code!<</blink>>"); else document.write("<<b>>Browser Not Known: Just a bold element!<</b>>");
There are a few problems with using browser detection this way. First, you are making an assumption that the browser will correctly report itself. You may find, in fact, that many obscure browsers will report themselves as Internet Explorer or Netscape because they do not want to be prevented from viewing sites coded to detect the major browser variants. You can start diving into the userAgent header, but even that can be completely spoofed. Second, you have to continually check the browser to write out the appropriate markup, littering your page with script code. We’ll see later on how we can redirect users or use other techniques to get around this. However, the third problem is the biggest: it is the assumption that simply knowing the browser type and version will be enough to determine what action to take. Developers should not focus on detecting the browser brand and version and then understand what that browser can or cannot do, but should instead focus on detecting the capabilities of the browser in use.