Handling Other Browsers If the user agent string contains the
word compatible followed by a semi-colon, the next word is
usually the manufacturer or browser name. Following the same
style as we did with the other two browsers, but not knowing the
manufacturer's web address, we can use this approach to make it
easy for visitors to search for their browser manufacturer on
the Web if they need an upgrade.
This code runs when we know that it's not a Microsoft
browser, and that it's probably not a Netscape browser either.
It pulls the manufacturer's name or browser name out of the user
agent string, and puts it in a hyperlink to the AltaVista search
engine:
...
If InStr(strUA, "compatible;") = 0 _
And InStr(strUA, "Opera") = 0 Then 'its probably a
Netscape browser
'...
'code for Netscape browser
'...
Else 'not Netscape, so we'll allow the user to search on the
Web for it
If InStr(strUA, "Opera") Then
'Opera 3.60 doesn't include 'compatible' in UA string
strProduct = Trim(Mid(strUA, InStr(strUA, ")") +
1))
Else
'use the part after the compatible keyword
strProduct = Mid(strUA, Instr(strUA, "compatible;")
+ 11)
strProduct = Trim(Left(strProduct, Instr(strProduct,
";") - 1))
End If
strSearchURL = "http://www.altavista.digital.com/cgi-bin/query?q="
_
& Server.URLEncode(strProduct & " web
browser")
Response.Write "Your browser is Navigator-compatible.
You can " _
& "search for the manufacturer using a search
engine, such as " _
& "<A HREF=" & QUOT & strSearchURL
& QUOT & ">" & strSearchURL _
& "</A></P>"
...
Notice how we have to perform a separate operation for Opera
3.60 because of the missing compatible keyword.
Here's how this works in that browser – you can see the URL
and query string displayed in the Web page. Each '+' sign
represents a space in the query string value, and the encoding
of the other characters such as the decimal point in the version
number and the square brackets is also visible as their URL
equivalents:
Clicking the link in the page opens the AltaVista search
results page with the results of a search on the browser name
and version:
Using The Browser Capabilities Component We've spent some
time on the contents of the user agent string, because it's
useful to know how to interpret it. However, there are
components we can use to make identifying browsers easier and
more accurate. The downside is that they are likely to impose a
heavier load on the server than the few simple lines of script
we've used so far.
ASP comes complete with a component called the Browser
Capabilities component. We met this in Chapter 2, when we used
it to figure out if the browser we were serving to supported
frames:
...
Set objBCap = Server.CreateObject("MSWC.BrowserType")
If Not(objBCap.frames) Then 'no frames support
Response.Clear
Response.Redirect "mainpage.asp"
End If
...
The Browser Capabilities component uses the user agent string
sent from the browser to identify it as accurately as possible.
In most cases, for all the common browsers, it will identify it
absolutely. This means that it can accurately report the various
abilities of that browser in detail.
In Windows 2000, there is a new version of the Browser
Capabilities component that adds a useful extra feature. It can
use client-side code to collect values from a specific user, as
long as their browser supports scripting. We'll come back to
look at this topic once we've examined how the component works.
The Browser Capabilities Information File The information
about all the browser types is stored in a text file named
browscap.ini, located in the same folder as the component on the
server. The default is Winnt\System32\inetsrv\ (or whatever the
path to the %system32% folder actually is on your machine). In
this file are sections for each browser user agent string, for
example:
[Mozilla/4.0 (compatible; MSIE 5.0; Windows 95)*]
parent=IE 5.0
platform=Win95
The third line shows that the parent for this entry is the
entry for IE 5.0, and that only the platform entry differs from
those of the parent. The parent entry (elsewhere in the file)
looks like this:
[IE 5.0]
browser=IE
Version=5.0
majorver=#5
minorver=#0
frames=TRUE
tables=TRUE
cookies=TRUE
backgroundsounds=TRUE
vbscript=TRUE
javascript=TRUE
javaapplets=TRUE
ActiveXControls=TRUE
Win16=False
beta=False
AK=False
SK=False
AOL=False
crawler=False
CDF=True
Each of the entries in the file is available as a property of
the component, so we can do things like this:
...
<%
Set objBCap = Server.CreateObject("MSWC.BrowserType")
'see if this browser supports ActiveX Controls
If objBCap.ActiveXControls Then
%>
HTML here to define the ActiveX Control for presenting some
information
<% Else %>
HTML here to use a different way of presenting the
information
<% End If %>
...
Note how the component exposes the browser make and version,
which saves us having to use script to get at it like we did
earlier:
...
strBrowserName = objBCap.browser 'a string defining the
manufacturer
sngBrowserVersion = CSng(objBCap.Version) 'a number for use
in comparison tests
...
You can edit the file yourself, and add other browsers. You
can also add extra properties, because the component
automatically exposes all the entries it finds as properties.
So, you could add the Web Home page URL for each browser to the
file if you wanted, making it easy to display it as a link (like
we did with ASP in our previous example). The file also accepts
wildcards, so you can – to some extent – future-proof for
new browser versions. For instance, an asterisk (*) matches any
combination of characters; so that [Mozilla/4.0 (compatible;
MSIE 5.*) *] means any MSIE version 5 browser on any platform.
If the component cannot find an entry for a browser, it sets all
the properties to the string "UNKNOWN".
The IIS documentation (http://localhost/iishelp/) contains
more details about the Browser Capabilities component. Look up
Browser Capabilities in the Index. You can also download the
latest version of the browscap.ini file from http://www.cyscape.com/browscap/.
Getting Client-Side Information With The Browser Capabilities
Component The new version of the Browser Capabilities component
that comes with ASP 3.0 in Windows 2000 has a neat feature that
allows us to collect information about each specific user's
browser, rather than just relying on the values that are generic
to each browser. Obviously, the browscap.ini file that the
Browser Capabilities component uses to identify the browser from
its USER-AGENT string can only contain general information that
applies to that browser. In other words, it can tell you if it
supports frames or ActiveX controls, but it can't tell you what
screen resolution (for example) the user is running in.
To be able to create pages that are tailored to individual
users, rather than individual browsers, we have to be able to
collect information that is specific to each user. This is done
by instructing the browser to return the information in a cookie
named BrowsCap, which the ASP interpreter sends and receives
when the page is first executed. The instruction that tells ASP
to do this is a special version of the METADATA element:
<!--METADATA TYPE="Cookie" NAME="BrowsCap"
SRC="url_of_page_that_creates_the_cookie"-->
ASP sees this element when loading the page, and does all the
work of sending and receiving the cookie. Then it takes the
values stored in the cookie and automatically adds them to the
values that are available from the browscap.ini file for that
browser. These values are only available for the duration of the
current page, so if you want to use them again you either have
to re-send the cookie (using the METADATA element again) or
store them somewhere on the server. The second option is
obviously the best, and a useful trick is to store them in the
user's Session object.
The Client-Side 'Create Cookie' Page We've provided a page
that creates a cookie (make_cookie.htm) containing client-side
information, and which works in IE4+ and Navigator 4+ (although
performance in Navigator is variable due to the caching of the
pages and cookie). The first part of the page defines an
IE5-specific ClientCaps behavior, and attaches it to an XML
element in the page. This allows us to access features and
settings of the browser directly. The ClientCaps behavior is
built into IE5, and provides a whole range of information about
the browser.
In the opening <BODY> tag, we also specify the function
createCookie, which will run when the page has loaded. Then
comes the start of the <SCRIPT> section where this
function is defined:
<HTML XMLNS:IE>
<HEAD>
<STYLE>
IE\:clientcaps {behavior:url(#default#clientcaps)}
</STYLE>
</HEAD>
<BODY ONLOAD="createCookie();">
<IE:clientcaps ID="objCCaps" />
<SCRIPT LANGUAGE="JavaScript">
<!--
function createCookie() {
var strCookie = new String();
...
Now we have to decide which browser we are running under, and
create the cookie to return to the server. If it's Navigator 4,
we can get values from the screen and navigator objects:
...
if (navigator.appName.indexOf('Netscape') != -1) {
if (navigator.appVersion.substr(0, 1) > 3) {
// Navigator 4 or higher
strCookie = 'width=' + window.screen.width
+ '&height=' + window.screen.height
+ '&availWidth=' + window.screen.availWidth
+ '&availHeight=' + window.screen.availHeight
+ '&bufferDepth=' + window.screen.pixelDepth
+ '&colorDepth=' + window.screen.colorDepth
+ '&javaEnabled=' + window.navigator.javaEnabled()
+ '&platform=' + window.navigator.platform
+ '&userLanguage=' + window.navigator.language;
}
}
...
If it's IE4, we can also use the screen and navigator
objects, though there are fewer properties available:
...
if (navigator.appName.indexOf('Microsoft') != -1) {
window.onerror = stopAllErrors;
intPos = navigator.appVersion.indexOf('MSIE') + 5;
strVersion = navigator.appVersion.substr(intPos, 1);
if (strVersion == 4) {
// Internet Explorer 4
strCookie = 'width=' + window.screen.width
+ '&height=' + window.screen.height
+ '&bufferDepth=' + window.screen.bufferDepth
+ '&colorDepth=' + window.screen.colorDepth
+ '&javaEnabled=' + window.navigator.javaEnabled()
+ '&cookieEnabled=' + window.navigator.cookieEnabled;
}
...
Notice that we can prevent any errors from causing a dialog
to be displayed by setting the onerror property of the window
object to a function that simply returns the value true:
function stopAllErrors() {
return true; // prevent display of any errors
}
If the browser is IE5, we can use the ClientCaps behavior
object that we created earlier in the page. This provides many
more properties that we can query:
...
if (strVersion > 4) {
// Internet Explorer 5 or higher
strCookie = 'width=' + objCCaps.width
+ '&height=' + objCCaps.height
+ '&availWidth=' + objCCaps.availWidth
+ '&availHeight=' + objCCaps.availHeight
+ '&bufferDepth=' + objCCaps.bufferDepth
+ '&colorDepth=' + objCCaps.colorDepth
+ '&javaEnabled=' + objCCaps.javaEnabled
+ '&cookieEnabled=' + objCCaps.cookieEnabled
+ '&connectionType=' + objCCaps.connectionType
+ '&platform=' + objCCaps.platform
+ '&cpuClass=' + objCCaps.cpuClass
+ '&systemLanguage=' + objCCaps.systemLanguage
+ '&userLanguage=' + objCCaps.userLanguage;
}
}
...
Once we've collected the values we need into our string, we
can assign it to the document's cookie property with the name 'BrowsCap'
(note that you must always use this name for the Browser
Capabilities component to be able to recognize the cookie:
...
document.cookie = 'BrowsCap=' + strCookie;
}
By temporarily adding the line:
alert(strCookie);
to the page, we can see the cookie that is created. Here it
is when the browser is IE5:
The Server-Side ASP Page Having created our client-side page,
we can now examine how we use it with the Browser Capabilities
component. The first step is to create an instance of the
component, and then provide the METADATA element that instructs
the component to send the make_cookie.htm page to the client. On
return, the values in the cookie are decoded and added to the
list of properties that are exposed by the Browser Capabilities
component:
<%@LANGUAGE="VBScript"%>
<%
'create an instance of the component
Set objBCap = Server.CreateObject("MSWC.BrowserType")
%>
<!--METADATA TYPE="Cookie" NAME="BrowsCap"
SRC="make_cookie.htm"-->
...
Now we can create a two-column table and place the values
from the Browser Capabilities component into it. We put the
values that come directly from the browscap.ini file in the
left-hand column:
...
<HTML>
<HEAD><TITLE>The Browser Capabilities
Component</TITLE></HEAD>
<BODY BGCOLOR="#FFFFFF">
<SPAN CLASS="heading">The Browser
Capabilities Component</SPAN><HR>
<!--------------------------------------------------------------------------->
<TABLE WIDTH="100%">
<TR><TD VALIGN="TOP">
<DIV CLASS="subhead">Values from
the<BR>browscap.ini file:</DIV>
browser: <B><% = objBCap.browser
%></B><BR>
version: <B><% = objBCap.version
%></B><BR>
majorver: <B><% = objBCap.majorver
%></B><BR>
minorver: <B><% = objBCap.minorver
%></B><BR>
frames: <B><% = objBCap.frames
%></B><BR>
tables: <B><% = objBCap.tables
%></B><BR>
cookies: <B><% = objBCap.cookies
%></B><BR>
backgroundsounds: <B><% = objBCap.backgroundsounds
%></B><BR>
vbscript: <B><% = objBCap.vbscript
%></B><BR>
javascript: <B><% = objBCap.javascript
%></B><BR>
javaapplets: <B><% = objBCap.javaapplets
%></B><BR>
activexcontrols: <B><% = objBCap.activexcontrols
%></B><BR>
AK: <B><% = objBCap.AK %></B><BR>
SK: <B><% = objBCap.SK %></B><BR>
AOL: <B><% = objBCap.AOL %></B><BR>
beta: <B><% = objBCap.beta %></B><BR>
Win16: <B><% = objBCap.Win16
%></B><BR>
Crawler: <B><% = objBCap.Crawler
%></B><BR>
CDF: <B><% = objBCap.CDF %></B><BR>
</TD>
...
Then, in the right-hand column, we place the values that have
been collected from the client and added to the list of
properties exposed by the Browser Capabilities component:
...
<TD VALIGN="TOP">
<DIV CLASS="subhead">Values from
the<BR>browser cookie:</DIV>
width: <B><% = objBCap.width
%></B><BR>
height: <B><% = objBCap.height
%></B><BR>
availWidth: <B><% = objBCap.availWidth
%></B><BR>
availHeight: <B><% = objBCap.availHeight
%></B><BR>
buffer/pixelDepth: <B><% = objBCap.bufferDepth
%></B><BR>
colorDepth: <B><% = objBCap.colorDepth
%></B><BR>
javaEnabled: <B><% = objBCap.javaEnabled
%></B><BR>
cookieEnabled: <B><% = objBCap.cookieEnabled
%></B><BR>
connectionType: <B><% = objBCap.connectionType
%></B><BR>
platform: <B><% = objBCap.platform
%></B><BR>
cpuClass: <B><% = objBCap.cpuClass
%></B><BR>
systemLanguage: <B><% = objBCap.systemLanguage
%></B><BR>
userLanguage: <B><% = objBCap.userLanguage
%></B><BR>
</TD></TR></TABLE>
</BODY>
</HTML>
And here's the result for IE5. You can see how the extra
client-specific properties provide useful information that you
can use to tailor your pages to that client, not only by sizing
it appropriately, but by changing the images to ones with a
suitable color depth, which will give optimal performance
depending on the connection type (which can be over a LAN or via
a modem):
The CyScape 'BrowserHawk' Component While the Browser
Capabilities component is a great deal quicker, easier and more
accurate than our attempts at browser detection with script,
it's still not perfect. Another approach is taken by CyScape
Inc, who not only provide updated versions of browscap.ini, but
also manufacture a component called BrowserHawk. This recognizes
many more different types of browsers, and provides a lot more
information about each one. There is also a version available as
a JavaBean. You'll find CyScape at http://www.cyscape.com/
BrowserHawk can tell you if the browser supports Style Sheets
and CSS, File Uploads, and SSL encrypted communication, as well
as many other features. In fact there is a whole section of the
site devoted to the advantages of BrowserHawk over the Browser
Capabilities component, starting at http://www.cyscape.com/browserhawk/intro.asp.
The latest version of BrowserHawk (BrowserHawk 2000) also
supports two new features. It can use a cookie to obtain
specific information from each client, in much that same way as
the Browser Capabilities component does. However, his feature
works in all IE, Netscape, Opera 3.x and upward browsers, not
just in IE5 as the method we described earlier with the Browser
Capabilities component. The user details that are available
include:
q Automatic detection of disabled JavaScript and disabled
Java applets
q Users screen size resolution and available browser window
height/width
q Detection of Macromedia Flash and Directory plugins
q Detection of user's connection speed in kilobits per
second!
q Detection of disabled cookies
BrowserHawk also offers a 'live update' feature, where the
server can query and automatically download and install new
versions of the configuration file direct from the CyScape Web
site at specific intervals.
To change over from the Microsoft Browser Capabilities
component to BrowserHawk is easy. You just download and install
BrowserHawk, then change the class string in the
Server.CreateObject statement that creates the component
instance to "cyScape.browserObj". The remainder of
your code (according to CyScape) will continue to work as
normal, though there is a section of their Web site devoted to
issues that may arise. For more information, or to download an
evaluation copy of BrowserHawk, go to http://www.cyscape.com/.
Back
| Contents | Next