WebReference.com - When You Can't Trust the Browser: the Lies Opera Tells (2/2) | WebReference

WebReference.com - When You Can't Trust the Browser: the Lies Opera Tells (2/2)

To page 1current page

When You Can't Trust the Browser

Opera's Little Lie

The user can change Opera's identifying user agent string in the preferences dialog. And starting with version 6 there is a 'Quick Preferences' dialog that makes it even easier:

Opera 6's Quick Preferences Menu
Opera 6's quick preferences menu lets you instantly pretend you are running a different browser.

Opera 5 Browser Connection Preferences
And both Opera 5 and Opera 6 allow for the direct setting of the browser identification in the preferences menu.

These are the userAgent strings returned from Opera 6 in each disguise: (the Windows XP bit would be replaced by whatever platform is used)

Identify as MSIE 5.0:

Mozilla/4.0 (compatible; MSIE 5.0; Windows XP) Opera 6.01  [en]

Identify as Mozilla 3.0:

Mozilla/3.0 (Windows XP; U) Opera 6.01  [en]

Identify as Mozilla 4.0:

Mozilla/4.78 (Windows XP; U) Opera 6.01  [en]

Identify as Mozilla 5.0:

Mozilla/5.0 (Windows XP; U) Opera 6.01  [en]

Identify as Opera:

Opera/6.01 (Windows XP; U)  [en]

Another interesting thing about all this is when you install Opera for Windows on a Windows machine, it starts out life with the IE identification, and not the 'Opera.'

The point is, if you have some code that is just for IE, you can't rely on testing for the MSIE in the uA string. The other ids just twiddle the version number, and don't cause the same potential for sleepless nights and unpleasant e-mail, but when an IE is not IE you can have problems.

You can definitely spot Opera by explicitly testing the string for the 'Opera,' which is always tacked on the uA string, in a kind of "I was only fooling" tail.

if(iz('IE') && navigator.userAgent.indexOf('Opera')== -1)

But that is just bad code. It's three times as long to write and makes the engine do two separate tests to find one thing.

Opera doesn't say much about the reasons for all this, although I believe there was a time when some large, well known sites didn't load all their pages if the userAgent failed the MSIE test.

Opera just says, in their documentation:

When a Web browser connects to a Web site, it tells the Web site which browser it is. In an ideal world, all browsers would work with all sites, but that is sadly not the case. Browsers work a bit differently, and some Web sites may intentionally or unintentionally shut out some browsers as a result.

If you experience problems with a Web site, try changing the browser identification and reload the page.

Are there end users who actually play with these settings?

It feels like a programmer's toy to me. Of course, I like toys. On the Opera site they have recently added some pretty good documentation, and it appears that a major reason for giving Opera the IE switch was to run a subset of Microsoft's J-script on top of the JavaScript that is standards supported. Now, J-Script is a whole 'nuther article...

To get back to the point, sometimes Opera can handle the code written for IE. Some of the form elements, links & anchors, and images behave fairly well with basic scripts. But you can't count on it.

That's the little lie. It helped me switch my strategy for browser testing away from the userAgent and toward actual browser capability. It is better to test the browser for what it can do, not what its name is. Or might be. For example:

Finding Ids

Say you want to find an element by its id.

function Mr(hoo){        
      return document.getElementById(hoo);
// document.all must come second, or Opera (with IE setting)
// and IE will use this method
   else if (document.all)
      return document.all[hoo];
   else if (document.layers)
      return document.layers[hoo];
   else return false;

If you are using Opera or IE5+ or Mozilla/N6 the first if, getElementById, will snag your man. IE4 will discover him with the all array, and Navigator might find the id, if the element is positioned and in the first level. If you write your code to run depending on the result of testing an if(Mr(hoo)) statement, you'll keep out the rif raff.

A test for (create.documentFragment) returns true for N6, Mozilla and IE6 but not IE5 or Navigator. This works for various methods in the document object model. Except...

The Big Lie

My favorite, separate the men from the boys, the wheat from the chaff, never fail, do or die browser test has been (document.createElement). If a browser client can create new elements in an open document, the page is wide open for scripting with document objects.

If the browser doesn't pass the document.createElement test, I either give it a document write to make new content, or a link to another page, or leave 'em the plain HTML--just like mother used to make.

I have a set of tests I use enough to keep in a single function, called iz. Remember iz? There is a set of strings you can send, to test for a few important abilities. My favorite is to test for (document.createElement).

I start countless scripts with a test like:

if(iz('DOM')) do a lotta DOM code;      
   else do some other code.

It has always worked--until the latest Opera version. Guess what Opera tells us?

Yep. Opera claims to understand document.createElement. So it gets in the approved section and in a microsecond it is asked to create an element and that's all, folks... it never sees the code written for the browsers that can't use createElement.

It goes to show, we cannot let up. No matter how carefully we test and retest, something will come along and break our code. We have to keep testing, keep checking, and never assume we know what is coming next.

So far Opera doesn't claim to support document.createTextNode, so with a quick edit, I recovered. My test in iz for the DOM now reads:

case 'dom':return !!(document.createTextNode);

But I'm not really comfortable with iz anymore...

About the Author

Kenneth Tibbetts is the creator of the Yankee Web Shop at http://www.yankeeweb.com/webshop.html and can be reached at: postmaster@yankeeweb.com.

To page 1current page

Created: April 1, 2002
Revised: April 1, 2002

URL: http://webreference.com/programming/javascript/operalies/2.html