Tuesday, April 10th, 2007

Capabilities vs. Quirks: When sniffing is OK

Category: Articles, Browsers, JavaScript

Andrew Dupont has written a detailed report on Capabilities vs. Quirks: a look at browser sniffing.

The purists go on a rant if they ever see you touch navigator.userAgent, but Andrew gives reasons why Prototype has items such as:


  1. Prototype.Browser = {
  2.   IE:     !!(window.attachEvent && !window.opera),
  3.   Opera:  !!window.opera,
  4.   WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
  5.   Gecko:  navigator.userAgent.indexOf('Gecko') > -1 &&
  6.           navigator.userAgent.indexOf('KHTML') == -1
  7. };

An example of a quirk that requires sniffing:

/* Force “Connection: close” for older Mozilla browsers to work
* around a bug where XMLHttpRequest sends an incorrect
* Content-length header. See Mozilla Bugzilla #246651.
if (this.transport.overrideMimeType &&
(navigator.userAgent.match(/Gecko/(d{4})/) ||
[0,2005])[1] < 2005) headers['Connection'] = 'close'; [/javascript]

This makes my eyes water whenever I look at it: we’re parsing out a year from a user agent string. But what else is there to do? Even if it’s possible to detect this quirk on the client side (and I’m not sure it is), it’d involve sending a dummy Ajax request on page load. Checking navigator.userAgent doesn’t look so ridiculous after all.

Posted by Dion Almaer at 7:27 am

4 rating from 26 votes


Comments feed TrackBack URI


Comment by ëï — April 10, 2007

Anyone using a Gecko-based browser from 2005 is prone to worse bugs than that, i see it ridiculous to support these kind of quirks.

Comment by gonchuki — April 10, 2007

The reason I don’t ever check the user agent string is because it can be spoofed by most browsers. While it’s a lofty ideal to use the same code for every browser, it’s not really realistic if you want your web application to work or look right. But object detection is far superior to user agent detection. You can effectively detect a lot of popular browsers with object detection:

if(document.all && !window.opera) var isIE = true;
if(document.all && !document.fireEvent && !window.opera) var isIE5 = true;
if(document.all && document.fireEvent && !document.createComment) var isIE55 = true;
if(document.compatMode && document.all) var isIE6 = true;
if(document.documentElement && typeof document.documentElement.style.maxHeight!="undefined" && !isSafari && !isGecko && !isOpera) var isIE7 = true;
if(!document.doctype && !isIE) var isSafari = true;
if(window.Iterator) var isGecko181 = true;
elseif(Array.every) var isGecko18 = true;
elseif(window.getComputedStyle && !window.opera) isGecko17 = true;
if(window.opera) var isOpera = true;

Comment by Trevor — April 10, 2007

very nice Trevor, just the piece of code i was looking for :)

Comment by Daniel Kraaij (DaanK Interworking) — April 11, 2007


Most of the credit belongs to http://www.javascriptkit.com/javatutors/objdetect3.shtml

Comment by Trevor — April 11, 2007

Leave a comment

You must be logged in to post a comment.