Chapter 29
General Software Detection
Browser Detection
A major problem with JavaScript is that it is not a compiled language but rather an
interpreted one. Furthermore, unlike a server-side Perl script, it is interpreted by a
different interpreter each time. For example, if you put some JavaScript code on a Web
page, it is interpreted by Netscape Navigator 2.0x, 3.0x, Microsoft Internet Explorer
3.0x, and so forth. Each of these browsers is available on various platforms, so there are
hundreds of possibilities (yes, hundreds!).
Some JavaScript features or elements are compatible only with some of the
JavaScript-enabled browsers. For example, the Image object is not supported by
Netscape Navigator 2.0x or MSIE 3.0x but is supported by Navigator 3.0x. In the heart of a
Web content provider, you usually want to make sure that your Web pages are compatible
with all browsers, or at least the most recent ones. For instance, if the most recent
browser is Navigator 3.0x, you would want your Web pages to be suitable for Navigator 2.0x
and MSIE 3.0x users. Microsoft, being aware of the differences between its implementation
of JavaScript and Netscape’s implementation, hurried to rename its JavaScript
“JScript.” There are basically two possibilities to provide Web pages that are
compatible with most, if not all, JavaScript browsers:
- You can choose to stick with the most scaled-down version of JavaScript. That is, make
sure that the page works with Netscape Navigator 2.0 and MSIE 3.0. This technique is
possible because newer browsers always support the features of those that precede them.
For example, JavaScript for Netscape Navigator 4.0 supports all features in JavaScript for
Netscape Navigator 3.0x. This remedy’s disadvantage is obvious—you cannot take
advantage of the powerful features supported only by the most recent JavaScript-enabled
browsers.
- You can use JavaScript to find out what browser the user is running, and provide scripts
of HTML content accordingly. You can invoke, for example, one function if the user is
running Netscape Navigator, and a different one if the user is running Microsoft Internet
Explorer. You can also use two different statements depending on the user’s platform
(e.g., Windows 95, Macintosh PPC).
What is the navigator
Object?
The navigator object does not belong to JavaScript’s bulk of browser
objects. It is an independent object, just like the Math object. This object
combines various methods and properties providing information related to the user’s
software. For example, you can use this object to detect the user’s browser, platform,
plug-ins, and many other essential pieces of information.
You do not create instances of the navigator object in order to use it. You
simply use the values of its properties and the values returned by its methods. Since the
main topic of this chapter is software detection, we will deal with this object throughout
the entire chapter.
Using the navigator Object
to Detect the User’s Browser and Platform
The navigator object features four properties on all versions of JavaScript:
- appName
- appVersion
- appCodeName
- userAgent
Figure 29-1 lists the value of each of these properties on Netscape Navigator 4.0
Preview Release 3 (Windows 95), and Figure 29-2 lists them on MSIE 3.0x (Windows 95).
Figure
29-1. Property dumps for the navigator object
under Netscape Navigator 4.0b3 (Windows 95).
Figure
29-2. Property dumps for the navigator object
under MSIE 3.0X (Windows 95).
Here is the script that we used to create these dialog boxes:
var text = ""
text += "navigator.appName = " + navigator.appName + "\n"
text += "navigator.appVersion = " + navigator.appVersion + "\n"
text += "navigator.appCodeName = " + navigator.appCodeName +
"\n"
text += "navigator.userAgent = " + navigator.userAgent
alert(text)
The User Agent
Among all properties, the most useful one is navigator.userAgent. The roots of
this property are held tightly in CGI programming. In the initial communication between
the client and the server during an HTTP request, the browser sends the server bits of
information, such as all the valid cookies stored on the client. Among this information,
the browser sends the user-agent string to the server. This string is available to a CGI
application through the HTTP_USER_AGENT variable. The exact definition of this variable is
the browser that the client is using to send the HTTP request. Its general format is as
follows:
software/version library/version
The navigator.userAgent variable is similar to the HTTP_USER_AGENT environment
variable. This property is a combination of the navigator.appCodeName and navigator.appVersion
properties. As a matter of fact, it is simply these two values separated by a slash.
Therefore the following expression evaluates to true:
navigator.userAgent == navigator.appCodeName + "/" +
navigator.appVersion
Determining the User’s
Browser
There are many ways to determine what browser the client is using, with the minimum
number of if statements. For example, you can use the following function:
function getBrowser() {
if (navigator.userAgent.indexOf("Mozilla/3.0") != –1)
return 3
if (navigator.userAgent.indexOf("MSIE 3.0") != –1)
return 1
if (navigator.userAgent.indexOf("Mozilla/2.0") != –1)
return 2
return 0
}
This function returns 3 if the client is running Netscape Navigator 3.0x, 2 if the
client is running Netscape Navigator 2.0x, 1 if the client is running Microsoft Internet
Explorer 3.0x, and 0 otherwise (any other JavaScript-enabled browser). We prefer to write
a customized function for each script. For example, a function to check if the client is
using Netscape Navigator would be the following:
function isNetscape() {
return navigator.appName == "Netscape"
}
Figures 29-1 and 29-2 are a good reference for the properties you can use to accomplish
your particular task.
Redirecting the User to a
Browser-Specific Page
The easiest way to provide a distinct page for users with different browsers is to
redirect some or all of them to another page. Here is a simple example, which loads a
distinct Web page if the client is running Navigator 3.0x:
function getBrowser() {
if (navigator.userAgent.indexOf("Mozilla/3.0") != –1)
return 3
if (navigator.userAgent.indexOf("MSIE 3.0") != –1)
return 1
if (navigator.userAgent.indexOf("Mozilla/2.0") != –1)
return 2
return 0
}
if (getBrowser() == 3)
location.href = "URL of Navigator 3.0x-specific page"
The problem with this technique is that the user must wait for the new page to load (if
he or she is using Netscape Navigator 3.0x). The first waiting period consists of the time
until the document containing this script begins to load and the script is interpreted. If
the client is using Navigator 3.0x, the condition getBrowser() == 3 evaluates to true,
and the user must wait until another page loads. In the following section, you will find
out how to use an interesting technique involving frames to avoid the long waiting period.