Client sniffer

Version 1.1 - 14th January 2005

This client sniffer is designed as a component to cross-browser DHTML (Dynamic HyperText Markup Language) scripting. It differentiates between Windows, Macintosh and Linux, and between the most commonly used DHTML browsers.

The script uses object and feature detection as much as possible, and defines browser variables based on known profiles of what a particular browser supports. This makes it more robust that conventional user-agent sniffing because it can still detect known browsers that are spoofing as something else.

Yet it is something of a perversion of object and feature detection to use it for detecting browsers. Instead of thinking feature x doesn't work in browser y, so let's test for that browser it's generally better to think feature x doesn't work in all browsers, so let's test for feature x. This is what feature detection really is.

But yet I've used it for browser detection because, well, it's needed. Browsers lie about what they support, or support something buggily, or only partially in a way that can't be expressed as a simple boolean. There will inevitably be situations when what you really need to know is the client browser - and that's what this script is for. You should use it (and all client-sniffers) with great care.

If scripting (or this script) is not supported, no data will be available.

Latest update

Version 1.1 extends the op7 variable to recognise Opera 8.

Get the script

Download the zipfile [1K] and unzip it into your site directory, then you can either include the script on your page as it is:

<!-- Client sniffer by Brothercake - http://www.brothercake.com/ -->
<script type="text/javascript" src="sniffer.js"></script>

or copy the code into another script, and work with it from there:

//CS1.1

///////////////////////////////////////
//
//  Client sniffer by Brothercake
//  http://www.brothercake.com/
//
///////////////////////////////////////

var exclude=1;
var agt=navigator.userAgent.toLowerCase();
var win=0;var mac=0;var lin=1;
if(agt.indexOf('win')!=-1){win=1;lin=0;}
if(agt.indexOf('mac')!=-1){mac=1;lin=0;}
var lnx=0;if(lin){lnx=1;}
var ice=0;
var ie=0;var ie4=0;var ie5=0;var ie6=0;var com=0;var dcm;
var op5=0;var op6=0;var op7=0;
var ns4=0;var ns6=0;var ns7=0;var mz7=0;var kde=0;var saf=0;
if(typeof navigator.vendor!="undefined" && navigator.vendor=="KDE"){
	var thisKDE=agt;
	var splitKDE=thisKDE.split("konqueror/");
	var aKDE=splitKDE[1].split("; ");
	var KDEn=parseFloat(aKDE[0]);
	if(KDEn>=2.2){
		kde=1;
		ns6=1;
		exclude=0;
		}
	}
else if(agt.indexOf('webtv')!=-1){exclude=1;}
else if(typeof window.opera!="undefined"){
	exclude=0;
	if(/opera[\/ ][5]/.test(agt)){op5=1;}
	if(/opera[\/ ][6]/.test(agt)){op6=1;}
	if(/opera[\/ ][7-9]/.test(agt)){op7=1;}
	}
else if(typeof document.all!="undefined"&&!kde){
	exclude=0;
	ie=1;
	if(typeof document.getElementById!="undefined"){
		ie5=1;
		if(agt.indexOf("msie 6")!=-1){
			ie6=1;
			dcm=document.compatMode;
			if(dcm!="BackCompat"){com=1;}
			}
		}
	else{ie4=1;}
	}
else if(typeof document.getElementById!="undefined"){
	exclude=0;
	if(agt.indexOf("netscape/6")!=-1||agt.indexOf("netscape6")!=-1){ns6=1;}
	else if(agt.indexOf("netscape/7")!=-1||agt.indexOf("netscape7")!=-1){ns6=1;ns7=1;}
	else if(agt.indexOf("gecko")!=-1){ns6=1;mz7=1;}
	if(agt.indexOf("safari")!=-1 || (typeof document.childNodes!="undefined" && typeof document.all=="undefined" && typeof navigator.taintEnabled=="undefined")){mz7=0;ns6=1;saf=1;}
	}
else if((agt.indexOf('mozilla')!=-1)&&(parseInt(navigator.appVersion)>=4)){
	exclude=0;
	ns4=1;
	if(typeof navigator.mimeTypes['*']=="undefined"){
		exclude=1;
		ns4=0;
		}
	}
if(agt.indexOf('escape')!=-1){exclude=1;ns4=0;}
if(typeof navigator.__ice_version!="undefined"){exclude=1;ie4=0;}

The scripting can go anywhere, but if you put it at the beginning of the <head> section, then any other scripts on the same page will have access to its variables.

Implementation notes

The script returns a set of browser variables:

Variable. Description
ie Internet Explorer 4+ and IE-based third-party browsers. You can also be more specific:
ie4 ... Internet Explorer 4 only.
ie5 ... Internet Explorer 5 or 6.
ie6 ... Internet Explorer 6 only.
ns4 Netscape 4.
ns6 Gecko and KDE-based browsers - which includes Nestcape 6 and 7, Mozilla, Konqueror and Safari. You can also identify smaller groups within this:
ns7 ... Netscape 7.
mz7 ... any gecko browser except Netscape. This is principally designed to identify Mozilla's own builds from Version 0.6 onwards, but it also returns true for any other non-netscape gecko browser.
kde ... Konqueror, from KDE 2.2 onwards.
saf ... Safari. This variable will identify Safari irrespective of which browser it's set to identify as.
op5 Opera 5.
op6 Opera 6.
op7 Opera 7 or later. This, and the previous two variables, will identify Opera irrespective of which browser it's set to identify as.

Underpinning these is a safety variable, for protecting legacy browsers:

Variable. Description
exclude Primitive javascript browsers such as Netscape 3.

There are also three OS (Operating System) variables:

Variable. Description
win Windows.
mac Macintosh.
lin Linux, or anything else.

and you can query a lower-case version of the user-agent string:

Variable. Description
agt User-agent string.

The sniffer variables are global, and therefore available to any other scripts on the same page. They allow you to code for or exclude specific browers, eg:

if (mac && ie5) { ... internet explorer 5 on a mac ... }
if (!ns4) { ... not netscape 4 ... }
if (win && (op5 || op6)) { ... a windows version of opera 5 or 6 ... }
if (ie5 || ns6 || op7) { ... ie5+, gecko, kde or opera 7 ... }

Remember that some browsers return true for more than one variable:

  • Internet Explorer 6 returns true for (ie6) and also for (ie)
  • Internet Explorer 5 or 6 return true for (ie5) and also for (ie)
  • Internet Explorer 4 returns true for (ie4) and also for (ie)
  • Konqueror returns true for (kde) and also for (ns6)
  • Safari returns true for (saf) and also for (ns6)
  • All Gecko-based browsers which aren't Netscape return true for (mz7) and also for (ns6)

The exclude variable returns true for all unspecified browsers. This is very useful for protecting them from scary code, eg:

if (!exclude) { ... 4+ browsers only ... }

You may find it necessary to use a combination of expressions to get to the browser you need, eg:

if (!exclude) 
{
	if (ns6 || op7) { ... gecko, KTHML or Opera 7 ... }
	else if (ie5) { ... internet explorer 5+ ... }
	else { ... any other 4+ browser ... }
}

There are several minor browsers which have enough DHTML support to pass one of the object tests, but not enough to be useful. The script specifically filters out (adds to the exclude group) - Espial Escape, ICEBrowser and OmniWeb.

Credits

Thanks to Mark Wilton-Jones, who gave me the information to get past browser spoofing in Escape, OmniWeb and Safari.

Get the script

Usability widgets

Website gadgets

Bits of site functionality:

Local network apps

Web-applications for your home or office network:

Components

Parts for other scripting:

Novelties

More amusing than useful:


In this area

Main areas


[brothercake] came here for something, and found something else