ASP 101 - Active Server Pages 101 - Web04
The Place ASP Developers Go!

Please visit our partners


Windows Technology Windows Technology
15 Seconds
4GuysFromRolla.com
ASP 101
ASP Wire
VB Forums
VB Wire
WinDrivers.com
internet.commerce internet.commerce
Partners & Affiliates














ASP 101 is an
internet.com site
ASP 101 is an internet.com site
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

ASP 101 News Flash ASP 101 News Flash



 Top ASP 101 Stories Top ASP 101 Stories
Migrating to ASP.NET
Getting Scripts to Run on a Schedule
The Top 10 ASP Links @ Microsoft.com

QUICK TIP:
Use the Literal Control for Precise Rendering
Show All Tips >>
ASP 101 RSS Feed ASP 101 Updates


Handling Other Browsers
Back Contents Next

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
©1999 Wrox Press Limited, US and UK.
Home |  News |  Samples |  Articles |  Lessons |  Resources |  Forum |  Links |  Search |  Feedback


The Network for Technology Professionals

Search:

About Internet.com

Legal Notices, Licensing, Permissions, Privacy Policy.
Advertise | Newsletters | E-mail Offers