User Agent Detection Logic

  • Thread starter Lasse Reichstein Nielsen
  • Start date
L

Lasse Reichstein Nielsen

Fotios said:
I have put together a flexible client-side user agent detector (written in
js). I thought that some of you may find it useful. Code is here:

http://fotios.cc/software/ua_detect.htm

My only real problem with this code, is the problem it tries to solve.

You are trying to make a white-list of allowed browsers. White-lists
are not a very good idea, since they require constant updating. A
black-list is better. If you give a warning for browsers that you know
are *not* compatible with your page, and you write code that works
with modern standards, then you will rarely have to update the list.
That is, give an unknown browser the benefit of the doubt.

You also base the detection solely on the navigator.userAgent string.
That is not a reliable method, as some browsers are known to fake that
string.

There are some minor stuff:

- You use parseInt with only one argument. (And which browser has the
length of an array as a string?)

- You use "new Array(elem1,elem2,...,elemn);", which doesn't seem to
initialize the array in Netscape 2.02 (nor does the length property
of the array work).

- You write <script language="JavaScript">, which is illegal in HTML 4+.
The type attribute is required.

The detector requires javascript 1.0 to work. This translates to
netscape 2.0 and IE 3.0 (although maybe IE 2.0 also works with it)

IE 2 didn't have scripting at all. That was introduced in IE 3.0b2,
IIRC. I don't think the script is compatible with Netscape 2.

/L
 
R

Richard Cornford

Fotios said:
I have put together a flexible client-side user agent detector (written
in js). I thought that some of you may find it useful. Code is here:

http://fotios.cc/software/ua_detect.htm

The detector requires javascript 1.0 to work. This translates to
netscape 2.0 and IE 3.0 (although maybe IE 2.0 also works with it)

User agent detecting is unnecessary in almost all cases but of the
methods that have been attempted the use of the browser's
navigator.userAgent string is easily the most useless as very few
current browsers report consistent or accurate information in this
string. Often in order to avoid this type of clumsy and misguided
detection categorising them as "unknown" or "declined" when their
JavaScript and DOM support is entirely up to the requirements of the
majority of scripts and their authors can see no reason for them to be
excluded just because some script author only knows enough to recognise
7 browsers by name.

<URL: http://jibbering.com/faq/#FAQ4_26 >

Richard.
 
F

Fotios

Hi guys,

I have put together a flexible client-side user agent detector (written in
js). I thought that some of you may find it useful. Code is here:

http://fotios.cc/software/ua_detect.htm

The detector requires javascript 1.0 to work. This translates to netscape
2.0 and IE 3.0 (although maybe IE 2.0 also works with it)

Cheers,
Fotios
 
R

Richard Cornford

Fotios said:
I rarely read something as inacurate as what you have just written.

So you haven't bothered to read the comp.lang.javascript FAQ before
posting then:-

<URL: http://jibbering.com/faq/#FAQ4_26 >

- as it says essentially the same thing. (Still, I don't expect you
would consider that a document that is subject the scrutiny and review
of all of the regular poster to this group as having anything accurate
to say on the subject of browser scripting.)
What about the fact that most script that goes around does not run
properly in more than one or two browsers?

"most script that goes around" is written (or more often cut-n-pasted)
by people who do not really understand what they are doing and should
not be taken as an example of best (and in many cases not even
acceptable) practice.
A detector is about "what is" not about "what ought to be".

So test "what is" not "what ought to be" which is what you are testing
by assuming that the navigator.userAgent string ought to be a
discriminating indicator of the type and version of a web browser. It is
not and has not been for quite some time now.

As it is your code will identify Konqueror 3 as IE, Netscape, Opera,
Konqueror and unknown depending on which of the userAgent string I
choose form the list of 20 odd provided in the drop-down in the
preferences. While the same script will be absolutely convinced that my
Palm OS web browser is IE 6, but a script that treats it as IE 6 will
fail horribly. To qualify as a "detector" a script should be expected to
produce discriminating results. The navigator.userAgent string just
cannot provide that.

But, as I said, it is almost never necessary to know the browser type or
version. Feature detection is the preferred strategy. A script author
should know what features a browser must support in order for a script
to work. Testing for the existence of those features prior to execution
allows a script to execute in any browser that supports them and if they
are not available it can cleanly and harmlessly exit. A strategy that is
only interested in "what is" available on the browser in question, but
without any interest in which browser that actually is. Also a strategy
that can work successfully in a completely unknown browser, exploiting
any browser up to its ability to support the script.

Richard.
 
F

Fotios

Hi Lasse,

thanks for taking the time to help me (or us) improve this code!
My only real problem with this code, is the problem it tries to solve.

You are trying to make a white-list of allowed browsers. White-lists
are not a very good idea, since they require constant updating. A
black-list is better. If you give a warning for browsers that you know
are *not* compatible with your page, and you write code that works
with modern standards, then you will rarely have to update the list.

I understand what you are trying to say but my experience from web
development says that if you want to play it safe you should only allow your
code to run on specific browsers - the browsers you have tested it with.
However, if you review the code you will see that is uses a list that is
both black and white; i.e. you can have both white listed and black listed
browsers (Black listing takes precedence)

That is, give an unknown browser the benefit of the doubt.

If you check the code you will see there is an option just for that (i.e.
whether you want to allow an unknown browser to continue or not)

You also base the detection solely on the navigator.userAgent string.
That is not a reliable method, as some browsers are known to fake that
string.

Well, let's say that I won't be interested in covering this case just yet.
AFAIK all major browsers have a default user agent string that is
distinctive in some way and the rest of them (not major) should as well.

There are some minor stuff:

- You use parseInt with only one argument. (And which browser has the
length of an array as a string?)
- You use "new Array(elem1,elem2,...,elemn);", which doesn't seem to
initialize the array in Netscape 2.02 (nor does the length property
of the array work).

You are right on both of these two remarks. The first one was due to my
sloppy testing of NN 2.0; I was getting an error and I assumed this was due
to wrong typing of the length property of arrays but further testing I just
did shows that this property is simply undefined (thus the error).

And yes, this style of Array initialization does not seem to work with NN
2.0.

So, what I still need to make this work under NN 2.0 is:
- write a function that counts the length of an array in a way that is JS
1.0 compatible.
- initialize the array with arr[index] = value; type of statements

I should have the revised version soon.

BTW, there is a great old browser software archive here:
http://browsers.evolt.org/

- You write <script language="JavaScript">, which is illegal in HTML 4+.
The type attribute is required.

Thanks for letting me know. I added it.

IE 2 didn't have scripting at all. That was introduced in IE 3.0b2,

Yeah, some crooked hypothesis making on my part there. That was Netscape's
golden era.

Later,
Fotios
 
F

Fotios

User agent detecting is unnecessary in almost all cases but of the
methods that have been attempted the use of the browser's
navigator.userAgent string is easily the most useless as very few
current browsers report consistent or accurate information in this
string. Often in order to avoid this type of clumsy and misguided
detection categorising them as "unknown" or "declined" when their
JavaScript and DOM support is entirely up to the requirements of the
majority of scripts and their authors can see no reason for them to be
excluded just because some script author only knows enough to recognise
7 browsers by name.

I rarely read something as inacurate as what you have just written.

What about the fact that most script that goes around does not run properly
in more than one or two browsers? A detector is about "what is" not about
"what ought to be".

F.
 
F

Fotios

So you haven't bothered to read the comp.lang.javascript FAQ before
posting then:-

<URL: http://jibbering.com/faq/#FAQ4_26 >

I do not need to read the FAQ before or after I post.
- as it says essentially the same thing. (Still, I don't expect you
would consider that a document that is subject the scrutiny and review
of all of the regular poster to this group as having anything accurate
to say on the subject of browser scripting.)

I don't know what to answer to you as I have not read the FAQ.
"most script that goes around" is written (or more often cut-n-pasted)
by people who do not really understand what they are doing and should
not be taken as an example of best (and in many cases not even
acceptable) practice.

Isn't it still a fact that most script that goes around is not
cross-browser?
I have also heard that no scripter really knows what he/she is doing. What
do you think about that?
So test "what is" not "what ought to be" which is what you are testing
by assuming that the navigator.userAgent string ought to be a
discriminating indicator of the type and version of a web browser. It is
not and has not been for quite some time now.

One can easily write a lynx-like user agent that supplies any user string
he/she damn pleases.
Why does that shatter the status of things? (The status being that all major
browsers have - and should have - distinctive default strings)
As it is your code will identify Konqueror 3 as IE, Netscape, Opera
Konqueror and unknown depending on which of the userAgent string I
choose form the list of 20 odd provided in the drop-down in the
preferences.

Well, if you change the string you are on your own.
While the same script will be absolutely convinced that my
Palm OS web browser is IE 6, but a script that treats it as IE 6 will
fail horribly. To qualify as a "detector" a script should be expected to
produce discriminating results. The navigator.userAgent string just
cannot provide that.

Only because you were naughty and you changed the string.
What is the motivation in coding for the miniscule percentage of users who
not only use virtually non-existent browsers but also play with their user
agent strings?
But, as I said, it is almost never necessary to know the browser type or
version. Feature detection is the preferred strategy. A script author
should know what features a browser must support in order for a script
to work.
Testing for the existence of those features prior to execution
allows a script to execute in any browser that supports them and if they
are not available it can cleanly and harmlessly exit. A strategy that is
only interested in "what is" available on the browser in question, but
without any interest in which browser that actually is. Also a strategy
that can work successfully in a completely unknown browser, exploiting
any browser up to its ability to support the script.

1. Detecting a browser type is not necessarily for scripting purposes. For
instance, you may not like the way something renders in gecko.

2. I don't want to build a detector every time depending on what I want to
use.

3. A generic feature based browser detector seems to be much more work than
the one I posted. If you build one let me know and I will give it a try.

F.
 
I

Ivo

Fotios said:
I do not need to read the FAQ before or after I post.

You won't be jailed, but it seriously harms both your insight and our
sympathy if you don't.
I have also heard that no scripter really knows what he/she is doing. What
do you think about that?

No one can speak but for themselves, especially if they spend their time
behind computer screens. I for one haven't a clue.
Only because you were naughty and you changed the string.
What is the motivation in coding for the miniscule percentage of users who
not only use virtually non-existent browsers but also play with their user
agent strings?

I started reading this thread with a positive feeling, but this turns sour.
What is the movitation behind writing a script that scrutinizes something so
irrelevant? The bottom line is the navigator agent string thing can be
changed at will both by browser-makers and end-users. Mine is a Shakespeare
quote.
If I want my script to bark up the document.images tree, I will not test for
document.styleSheets or screen.availWidth or navigator.anyThing.

Regards,
Ivo
 
F

Fotios

Hi,

I have amended the code in a few places in order to be Netscape 2.0 (JS 1.0)
compatible:

* The JS1.0 parseFloat() function needed some help as it returns 0 (instead
of the NaN in later JS versions) when the initial char of the string is not
a digit.
There is now a helper function named: skipNonDigits()

* The array is now populated in a way that is JS 1.0 compatible

* I use substring() instead of substr(). This is because the former seems to
be working better in Netscape 2.0 although both are supported by JS 1.0

* In lack of the length property for arrays under JS 1.0 the length of the
browser array needs to be specified by the user along with the rest of the
parameters.

Revised code here:

http://fotios.cc/software/ua_detect.htm

Cheers,
Fotios
 
F

Fotios

You won't be jailed, but it seriously harms both your insight

maybe, but it helps uncalcify my thinking.
and our
sympathy if you don't.

awwwww! Please? Pretty Please?

No one can speak but for themselves, especially if they spend their time
behind computer screens. I for one haven't a clue.

This philosophy of yours is very deep.

The bottom line is the navigator agent string thing can be
changed at will both by browser-makers and end-users. Mine is a Shakespeare
quote.

my friend, you are too kewl!

If I want my script to bark up the document.images tree, I will not test for
document.styleSheets or screen.availWidth or navigator.anyThing.

In your limited universe (browser detection) = (browser detection for
javascript running purposes)

Regards,
Ivo

More regards,
Fotios
 
F

Fotios

Not to mention credibility. He multi-posted these same thoughts in the
microsoft.public.scripting.jscript NG
<snip>

I do not see what credibility has to do with posting in two groups instead
of one.
Then again, if it is so, I wonder how this original theory of yours applies
to multi-NG whiners.


hey, you found company! You guys should build on this.

F.
 
S

Steve van Dongen

Isn't it still a fact that most script that goes around is not
cross-browser?

Who knows.
I have also heard that no scripter really knows what he/she is doing. What
do you think about that?

I think that sounds like flame bait. I think that if you believe
that, then you just insulted yourself. I think you need better
sources of information. I think that if you stick around the
newsgroup for a while you will discover that statement is wrong.
2. I don't want to build a detector every time depending on what I want to
use.

Yeah, if you want to test whether the browser is capable of doing,
say, image rollovers, writing
var fSupportsScriptableImages = (document.images ? true : false);
sure is a real pain.
3. A generic feature based browser detector seems to be much more work than
the one I posted. If you build one let me know and I will give it a try.

No one would ever write a "generic feature based browser detector".
Whatever that is. You don't need to know every feature the browser
supports; you only need to know if it supports the specific feature(s)
you are trying to use.

This isn't an argument you'll win; feature/object detection has long
been recommended over browser detection. It's less prone to error and
it requires less maintenance because it's backward and FORWARD
compatible.

Regards,
Steve
 
D

Dr John Stockton

JRS: In article <[email protected]>, seen in
news:comp.lang.javascript said:
I do not need to read the FAQ before or after I post.

It would, however, be a useful precaution against appearing to be a
person of inadequate sagacity. Of course, that appearance would in that
case not be misleading.
 
F

Fotios

I think that sounds like flame bait. I think that if you believe
that, then you just insulted yourself. I think you need better
sources of information. I think that if you stick around the
newsgroup for a while you will discover that statement is wrong.

Looks like you are biting. BTW, I have been around this group for years.
Yeah, if you want to test whether the browser is capable of doing,
say, image rollovers, writing
var fSupportsScriptableImages = (document.images ? true : false);
sure is a real pain.

Wouldn't you rather skip that part?
No one would ever write a "generic feature based browser detector".
Whatever that is.

Yeah, I suppose it is not mentioned in the FAQ; so FAQ puppies get
short-circuited.
This isn't an argument you'll win; feature/object detection has long
been recommended over browser detection.

This world is not black and white. Browser detection using the useragent
string still has a place and a function for the reasons I mentioned and
without claiming it is a panacea.

BTW, I am still waiting for your answer on the rest of my points about why
one would use useragent string based detection.

F.
 
F

Fotios

It would, however, be a useful precaution against appearing to be a
person of inadequate sagacity. Of course, that appearance would in that
case not be misleading.

This is a javascript group doc. If you are looking for sagacity per se maybe
you are looking in the wrong place. If your way of achieving sagacity is
reading JS FAQs then maybe you ought to wonder if something is wrong with
you. Finally, if you wish to rephrase the syntactic and semantic abomination
you just posted, I'll still read it (although I don't know if I really
should).

F.
 
R

Richard Cornford

Fotios said:
I do not need to read the FAQ before or after I post.
I don't know what to answer to you as I have not read
the FAQ.

You could try to explain why you "do not need to read the FAQ". It
certainly isn't because you are already familiar with its contents, or
that you know JavaScript and browser scripting better than its
collective authors (though it may be because you believe one, or both,
of those to be the case).

Isn't it still a fact that most script that goes around
is not cross-browser?

Yes, it is also a fact that some scripts do not even manage to be
multi-browser (which is all that your scripting actually aspires to be,
judging by your other posts in this thread). But why would
comp.lang.javascript promote the lowest common denominator as the
acceptable standard in a world where the norm is so poor? In fact the
poverty of the mass of current Internet script authoring is probably the
best justification for promoting only the highest standards in browser
scripting: True cross-browser scripting; authoring for any and every
browser, including the ones that will not execute JavaScript at all. And
the only strategy that is capable of delivering scripts that function,
or gracefully degrade (as appropriate), in JavaScript enabled browsers
is feature detecting to determine browser support for the features
required by the script.
I have also heard that no scripter really knows what
he/she is doing. What do you think about that?

If you did hear that it will have been from the lips of someone who did
not know what they were doing and was looking to justify their
unwillingness to find out.
One can easily write a lynx-like user agent that supplies
any user string he/she damn pleases.

It appears (from existing web browsers) that it is not too difficult to
write an IE-like web browser that supplies whatever user agent string
the user chooses (or its authors prefer). It has been done, many times.
Why does that shatter the status of things? (The status being
that all major browsers have - and should have - distinctive
default strings)

Of what value is it that some browsers have default user agent string
that are distinct from each other when they are indistinguishable from
the user agent strings of a cluster of other browsers? Of what value is
it when those strings are only the default values and the user has easy
access to mechanisms for changing them; mechanisms that (usually) have
zero impact on the actual abilities of the browser? And why "should
have"? Because it suites you?

The status of things is that the navigator.userAgent string is no longer
a discriminating identifier of web browsers and, if it ever was, it
never will be again.
Well, if you change the string you are on your own.

Web browsers are user configurable software. If the user has the options
in the software preferences then it is just unrealistic not to expect
them to configure their browser to reflect their preferences. In all of
the web site/application specifications I have seen to date I have seen
requirements to work with only a limited set of named browsers/versions
and even requirements to work only with JavaScript enabled browsers but
I have never seen it stated that scripts were only required to work with
those browsers in their _default_ configurations.

Of course your "browser detecting" followed by the assumption that
everything is then going to be the way that you are expecting it is
going to fall down with many non-default configurations even on IE.
Only because you were naughty and you changed the string.

No I did not. Pals OS web browser is just one of a number of browsers
that use a user agent string that is indistinguishable from an IE user
agent string, and it doesn’t give the user any direct access to
alternatives. And indistinguishable means indistinguishable, there is no
telling substring that can be used to distinguish them from IE versions
(on the Palm even the reported OS is fictional).
What is the motivation in coding for the miniscule percentage
of users who not only use virtually non-existent browsers
but also play with their user agent strings?

Because feature detecting does not have any interest in the type or
version of the web browser so there is no extra effort or work involved
in coping with any minority browser. (assuming of course that these
browsers that are indistinguishable from IE are actually minority
browsers. It is impossible to tell if they always appear in the browser
statistics as IE). You just write the script and if the browser supports
the required features then you are in business and if not its time to
gracefully degrade.
1. Detecting a browser type is not necessarily for scripting
purposes. For instance, you may not like the way something
renders in gecko.

Rendering is presentation, so CSS. Use CSS solutions for CSS problems,
involving scripting is unnecessary (and unreliable) but you cannot make
a discriminating identification of a Gecko browser from its user agent
string anyway as several Gecko variants (most notably Gostzill) are ser
up to report any of a range of preference settable userAgent strings
(including spoofing IE 100%) and a few even provide the user with the
option to type in anything they want as a user agent string. (these are
normal GUI configuration settings available under preferences not some
devious hack. However, all Gecko userAgent strings are amenable to
alteration by devious hack as well).
2. I don't want to build a detector every time depending
on what I want to use.

You are still thinking in terms of browser detecting. Feature detecting
is an integral part of scripting; there is no distinct "detector" at
all.
3. A generic feature based browser detector seems to be
much more work than the one I posted. If you build one
let me know and I will give it a try.

The reason that I use the term "feature detecting" as opposed to the
more common term "object detecting" (apart from the fact that you also
have to be testing functions, properties with primitive values and
sometimes language implementation characteristics) is that "object
detecting" is associated with attempts to detect browser types and
versions based on objects present in their DOMs. That technique was
widely adopted when it initially became clear that browser detecting
based on userAgent strings was no longer viable and initially produced
code like:-

var isIE = document.all?true:false;
var isNet4 = document.layers?true:false;

The response to this type of browser detecting (attempts at a generic
object detecting based browser detector) was that other browser
manufacturers started implementing document.all collections, or
document.layers collections or any other object/feature that someone had
hit upon as a discriminating indicator of a particular browser. And they
did this for exactly the same reasons that they started spoofing each
other’s user agent strings in the first palace. We now live in a world
where as many browsers have a document.all collection as don’t and the
last thing that its presence in a DOM means is that the browser is IE.

And it goes on; someone hits upon the idea of using the ActiveXObject
constructor as a discriminating indicator of IE 5+ and then uses that to
exclude non-IE 5+ browsers, and then we find that IceBrowser 5 has an
ActiveXObject constructor.

Pick a feature as a discriminating indicator of a browser and implement
your browser detecting based on that and the next thing you know a
couple of other browsers will have implemented that feature, or faked
it, and your browser detecting script is no longer doing what it was
designed to do.

The recurring theme here is that the purpose that you, and most others,
put browser detecting to motivates the browser manufacturers (including
Microsoft; witness the "Mozilla 4.0" that its userAgent string starts
with) to do what ever it takes to sidestep that browser detection.

The result is that browser detection as a practice has resulted in its
own invalidity.

The solution is to abandon browser detection as an idea and concentrate
on detecting the specific features that a script actually needs in order
to run. Never interested in the type of version of the browser, never
assuming that the existence of on feature implies the presence of
another and resulting in scripts that do what they can when they can and
fail cleanly when they can't, even on the browsers that will not be
released until next year and whose names are as yet unknown.

Richard.
 
F

Fotios

You could try to explain why you "do not need to read the FAQ".

Sure. For the same reason I do not need to read the bible in order to be a
good Christian.
I suppose one can find many similar ways to explain what you asked.

I'll tell you the truth tho. I have read the FAQ about 2 years back.
Since then so much has happened that I do not even remember what was in
there and what not.
It
certainly isn't because you are already familiar with its contents, or
that you know JavaScript and browser scripting better than its
collective authors
(though it may be because you believe one, or both,
of those to be the case).

I don't even ponder over such questions. It is just that I like solving
problems on my own. I am in this business strictly for the fun that this
entails.
Yes, it is also a fact that some scripts do not even manage to be
multi-browser (which is all that your scripting actually aspires to be,
judging by your other posts in this thread).

Well, the scripts that I have posted are certainly multi-browser so what you
say here is obviously wrong.
True cross-browser scripting; authoring for any and every
browser, including the ones that will not execute JavaScript at all. And
the only strategy that is capable of delivering scripts that function,
or gracefully degrade (as appropriate), in JavaScript enabled browsers
is feature detecting to determine browser support for the features
required by the script.

Read below for an answer to that.
If you did hear that it will have been from the lips of someone who did
not know what they were doing and was looking to justify their
unwillingness to find out.

You sound hurt. Why don't you tell us what else you do well except scripting
(if we assume that you even do that well).
Maybe you can prove that you don't have any ego-related reason in making
this claim.

Of what value is it that some browsers have default user agent string
that are distinct from each other when they are indistinguishable from
the user agent strings of a cluster of other browsers? Of what value is
it when those strings are only the default values and the user has easy
access to mechanisms for changing them; mechanisms that (usually) have
zero impact on the actual abilities of the browser? And why "should
have"? Because it suites you?

Have you ever wondered why the user agent string is there at all? Why was it
introduced and kept in countless versions and builds?

I quote from RFC 2616:
----
14.43 User-Agent

The User-Agent request-header field contains information about the
user agent originating the request. This is for statistical purposes,
the tracing of protocol violations, and automated recognition of user
agents for the sake of tailoring responses to avoid particular user
agent limitations. User agents SHOULD include this field with
requests. The field can contain multiple product tokens (section 3.8)
and comments identifying the agent and any subproducts which form a
significant part of the user agent. By convention, the product tokens
are listed in order of their significance for identifying the
application.

User-Agent = "User-Agent" ":" 1*( product | comment )

Example:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3
----

After all the computer world only revolves because there are standards that
are followed by majorities.

The status of things is that the navigator.userAgent string is no longer
a discriminating identifier of web browsers and, if it ever was, it
never will be again.

The point is that it should be.On the other hand perhaps your faith that
object/property testing will remain a good way to test is overly inflated.

Web browsers are user configurable software. If the user has the options
in the software preferences then it is just unrealistic not to expect
them to configure their browser to reflect their preferences. In all of
the web site/application specifications I have seen to date I have seen
requirements to work with only a limited set of named browsers/versions
and even requirements to work only with JavaScript enabled browsers but
I have never seen it stated that scripts were only required to work with
those browsers in their _default_ configurations.

You are not supposed to fake user agent strings. Period.
This feature has only become available in various browsers and only because
it is very easily implementable.

Of course your "browser detecting" followed by the assumption that
everything is then going to be the way that you are expecting it is
going to fall down with many non-default configurations even on IE.

What percentage do you think? I say it works 99%.
No I did not. Pals OS web browser is just one of a number of browsers
that use a user agent string that is indistinguishable from an IE user
agent string, and it doesn't give the user any direct access to
alternatives. And indistinguishable means indistinguishable, there is no
telling substring that can be used to distinguish them from IE versions
(on the Palm even the reported OS is fictional).

Too bad. I think Opera also had the unfortunate idea of defaulting to
completely faking the IE ua string a few versions back. It seems they did
not keep it up for long.

(assuming of course that these
browsers that are indistinguishable from IE are actually minority
browsers. It is impossible to tell if they always appear in the browser
statistics as IE).

Heh, sorry but this reminds me of comical Ali.

Rendering is presentation, so CSS. Use CSS solutions for CSS problems,

Yeah but CSS does not always work the way one wants and the detection is
done in JS not CSS.

You are still thinking in terms of browser detecting. Feature detecting
is an integral part of scripting; there is no distinct "detector" at
all.

wow, that is tew kewl (and deep).

A few points to keep you busy:

* Should every browser preferably have a distinctive user agent string or
not? Don't read the RFC just use your common sense.

* You are trying to make a rule out of the exception (exception being the
faked strings)

* I can write a user agent that fakes the existence of certain JS objects
but provides others while for the faked ones has Shakespeare quotes as the
return value of various methods. I could name this product Fudgilla (create
say 10 variants of it under different names like Geekzilla), make it freely
available to the geek crowds and then argue that because these products
exist the feature detection method is no good anymore for deciding what kind
of browser we got.

Don't scratch your head too hard.

F.
 
L

Lasse Reichstein Nielsen

Fotios said:
Well, the scripts that I have posted are certainly multi-browser so what you
say here is obviously wrong.

Uhm, no. He said that it is multi-browser, but not cross-browser, so
you agree with him.
Have you ever wondered why the user agent string is there at all? Why was it
introduced and kept in countless versions and builds? ....

User-Agent = "User-Agent" ":" 1*( product | comment )

Example:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

It is *not* followed by the majorities. Internet Explorer doesn't follow it!

IE claims to be Mozilla/4.0 and then adds a comment saying that it is really
(Compatible; MSIE 6,0;...).

Every time someone makes a page that restricts access to some
browsers, most likely including IE, a browser will change, or allow
the user to change, how it identifiers itself. It does that, not because
it doesn't care about the standard, but because it has to work in a world
where page authors force them to lie.
The point is that it should be.

The point is also that browser detection shouldn't be necessary.

But it isn't. Browsers should support standards, but the most widely
used browser doesn't understand proper CSS 2 and doesn't follow the W3C
DOM specifications.
On the other hand perhaps your faith that object/property testing
will remain a good way to test is overly inflated.

Care to explain why?
You are not supposed to fake user agent strings. Period.

You are not supposed to restrict access to a page based on the
browser. That is counter to the very basic concept of the web.
But they do, and browsers adapt.

It is sad that faking your user agent string is necessary, but
blame the page authors, not the browser vendors or users. They
started it.
This feature has only become available in various browsers and only
because it is very easily implementable.

And not because there was a need?
Do you really mean that?
* Should every browser preferably have a distinctive user agent string or
not? Don't read the RFC just use your common sense.

They should.
Do they? No.
Your code is meant to solve a real life problem: That browsers are different.
In an ideal world, your program is not necessary.
In the real world, it should consider the real life problem that the user
agent string can not be trusted in all cases.

I don't know the percentage of people faking their user agent string.

I do when I access MSDN, because otherwise they won't show me the
page. I am smart enough to handle it in Proximitron, so not all pages
are affected. Not everyone is.

I do know that your program would have problems with detecting Netscape 4,
since it identifies itself as Mozilla/4, and so does IE.

Your test relies on the comment part of the userAgent string to identify
IE, which is not following the standard anyway.

Built-in user-agent strings in the browsers you try to identify.
Opera:
Opera/7.20 (Windows NT 5.1; U) [en]
Mozilla/5.0 (Windows NT 5.1; U) Opera 7.20 [en]
Mozilla/4.78 (Windows NT 5.1; U) Opera 7.20 [en]
Mozilla/3.0 (Windows NT 5.1; U) Opera 7.20 [en]
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1) Opera 7.20 [en]

Netscape 4.08:
Mozilla/4.08 [en] (WinNT; I ;Nav)

Mozilla Firebird 0.6
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4b) Gecko/20030516 Mozilla Firebird/0.6
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)
Mozilla/4.8 [en] (Windows NT 5.0; U)
Opera/7.11 (Windows NT 5.1; U) [en]

Internet Explorer 6:
Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; MyIE2; .NET CLR 1.1.4322)

This doesn't count browsers on other platforms, still mostly Mac and
Unix, but increasingly also mobile devices.

/L
 
R

Richard Cornford

Sure. For the same reason I do not need to read the
bible in order to be a good Christian.

Judging by your posts to microsoft.public.scripting.jscript under this
subject you are not a good Christian so perhaps you should RTFM.
I suppose one can find many similar ways to explain
what you asked.

And they could all be equally misguided.
I'll tell you the truth tho. I have read the FAQ about
2 years back. Since then so much has happened that I do
not even remember what was in there and what not.

So you read the explanation of the futility of browser detecting and the
recommendations of better alternatives and then went and spent the
intervening years writing scripts based on browser detecting?

Well, the scripts that I have posted are certainly
multi-browser so what you say here is obviously wrong.

You have suffered a deficit in English comprehension.

You sound hurt.

You think? I can see not reason for assuming that I would have any
emotional response to a hearsay report of an assertion by third party
who cannot be qualified to judge the validity of their own statement.
Why don't you tell us what else you do well except scripting

That would be irrelevant to a discussion of browser scripting and OP for
this newsgroup.
(if we assume that you even do that well).

Why make assumptions when you have access to information.
Maybe you can prove that you don't have any ego-related
reason in making this claim.

I can prove that as easily as you can prove that you heard the assertion
in the first place.

Have you ever wondered why the user agent string is there at all?
Why was it introduced and kept in countless versions and builds?

I haven’t had to wonder for as long as I have known. But before I knew I
don’t recall caring.
I quote from RFC 2616:
----
14.43 User-Agent

The User-Agent request-header field contains information about the
user agent originating the request. This is for statistical purposes,
the tracing of protocol violations, and automated recognition of user
agents for the sake of tailoring responses to avoid particular user
agent limitations. User agents SHOULD include this field with
requests. The field can contain multiple product tokens (section 3.8)
and comments identifying the agent and any subproducts which form a
significant part of the user agent. By convention, the product tokens
are listed in order of their significance for identifying the
application.

User-Agent = "User-Agent" ":" 1*( product | comment )

Example:

User-Agent: CERN-LineMode/2.15 libwww/2.17b3

RFC 2616 is the HTTP 1.1 standard. Can you point me to a standard that
says that the string used in the user agent header in HTTP 1.1 should be
made available to client-side scripting? No . . . perhaps some caution
should be exercised before citing standards as a justification for
client side browser detecting based on that string.

But standard hang heavily upon the words MUST (compulsory), SHOULD
(probably should be treated as compulsory) and MAY (clearly optional
(but possibly recommended)).

In the User Agent specification we find a SHOULD:-

<quote>
User agents SHOULD include this field with requests.
</quote>

And our browsers are complying by sending that header (100% to the
specification). As to the contents of that header we read:-

<quote>
The field can contain multiple product tokens (section 3.8) and comments
identifying the agent and any subproducts which form a significant part
of the user agent. By convention, ...
</quote>

- and the operative word is CAN, not MUST, not SHOULD, not even MAY but
CAN. Clearly the specification leaves the contents of the string up to
the implementer. That is not surprising because this was 1999 and IE was
already spoofing Netscape 4’s UA string so placing any strong
requirements on the content of the string would have been closing the
stable door after the horse has bolted.

So if a browser sends any user agent header it is conforming to the
letter of RFC 2616. The only way in which it can be considered as not
conforming to the standard that you cited is that it may not follow the
spirit of the standard. However, RFC 2616 starts:-

<quote>
The User-Agent request-header field contains information about the user
agent originating the request.
</quote>

-and our browser's User Agent headers are sending information about
themselves. It may not be very useful information, asserting little more
than that they consider themselves to be user agents, but that is still
information.

RFC 2616 then goes on:-

<quote>
This is for statistical purposes,
</quote>

Which is fine as the information can be used for statistical purposes.
You can use it to count the number of requests from software that
asserts its user agentness.

The spirit of:-

<quote>
the tracing of protocol violations,
</quote>

- can be conformed with by not making protocol violations (so there is
no need to trace them).

And it was the abuse of:-

<quote>
and automated recognition of user agents for the sake of tailoring
responses to avoid particular user agent limitations.
<quote>

- by not using the UA information to _avoid_ particular user agent
limitation, but rather to avoid dealing with those limitations by
blocking unrecognised and unwanted user agents, that caused the User
Agent string to become close to meaningless in the first place. But if
the browser manufacturers do not believe their browser to suffer from
limitations then there is no reason for them to need a response tailored
any differently to Some other browser’s.

But in all of this I do not see it stated that the User Agent header
MUST (even SHOULD) contain a discriminating identifier of the user agent
software. The closest RFC 2616 comes to that is to suggest that such an
identifier is an option.
The point is that it should be.

Says who? Apparently not RFC 2616.
On the other hand perhaps your faith that object/property
testing will remain a good way to test is overly inflated.

If it was a personal belief, unsupported by facts, at odds with expert
opinion and contrary to logic then I might question it. Fortunately that
is not the case.
You are not supposed to fake user agent strings. Period.

Again, says who?
This feature has only become available in various browsers
and only because it is very easily implementable.

Ease of implementation is far from the reason (let alone the only
reason) that this has become available. It has happened because browser
detection based on user agent strings (even if all browsers did use a
discriminating string) requires so much data to implement effectively
that it never has been, and the consequences were that unrecognised
browsers were excluded from sites for no better reason than that they
could be discriminated from recognised browsers. And so the
manufacturers of the unrecognised browsers became motivated to make
their browsers indistinguishable from the recognised browsers so that
the misguided script authors had no way of excluding them.

It is browser detecting as a practice that is the problem. It doesn’t
matter how it is done, whatever method is used will result in that
method becoming ineffective. It is just the case that userAgent string
based browser detecting became ineffective long ago and the smart
scripters moved on to something better.
What percentage do you think? I say it works 99%.

Given that browser usage statistics are notoriously based on a faulty
premise and that a browser that sends a user agent string that is
indistinguishable from IE’s will be reported as IE making it impossible
to even guesstimate their usage I think that the question is futile. But
common reported statistics for browsers with JavaScript unavailable or
disabled seem to be in the 8-12% range so no script could "work" more
than 88-92% (if you define work as successfully execute). Disabling
JavaScript is just one of the many ways in which browsers can deviate
form their default settings (though some default to having JavaScript
disabled in the first place so enabling it is non-default), I would
imagine that almost everyone plays with their settings at some point
(even if they just screw something up and end up having to re-set the
defaults in the end).

Heh, sorry but this reminds me of comical Ali.

You see a flaw in the logic?
Yeah but CSS does not always work the way one wants and the
detection is done in JS not CSS.

Go and ask in comp.infosystems.www.authoring.stylesheets and they will
tell you how to use CSS to fix rendering glitches in browsers. They will
also tell you (every last one of them) that you do not _ever_ use
JavaScript to fix CSS problems.
wow, that is tew kewl (and deep).

There is nothing like a well reasoned argument.
A few points to keep you busy:

* Should every browser preferably have a distinctive user agent
string or not? Don't read the RFC just use your common sense.

The RFC doesn’t say that they have to (only that they send the UA
header), and I can see not reason why they should as there is no need to
be interested in specific browser types anyway. I also can’t see any
reason for the UA string to be exposed to client side scripting for much
the same reason.
* You are trying to make a rule out of the exception (exception
being the faked strings)

I am trying to demonstrate that the proposition that it is possible to
use the navigator.userAgent string to uniquely identify web browsers is
false.

It is in the nature of logic that a billion instances of circumstances
corresponding with a proposition do not prove that proposition to be
true, yet just one instance (properly verified) of circumstances failing
to correspond with the proposition do _prove_ it to be false. And we do
not have just one instance where browser detection by userAgent string
will fail to identify a browser (or will misidentify it) we have many.

The proposition that it is possible to use the navigator.userAgent
string to uniquely identify web browsers _is_ false.
* I can write a user agent that fakes the existence of certain
JS objects but provides others while for the faked ones has
Shakespeare quotes as the return value of various methods. I
could name this product Fudgilla (create say 10 variants of it
under different names like Geekzilla), make it freely available
to the geek crowds and then argue that because these products
exist the feature detection method is no good anymore for deciding
what kind of browser we got.
<snip>

That would be your prerogative and feature detecting can cope with that.
It is exactly the sort of situation that it is expected to cope with
anyway. On discovering that your browser does not support the required
features it would cleanly degrade as designed. Your approach, on the
other hand, only offers the options of refusing the browser access (and
encouraging another round of UA string faking) or erroring until it made
a very ungraceful exit.

On the other hand, is it likely that a new browser would be introduced
that deliberately re-defined the DOM to the extent that you describe?
Reality seems to be moving towards standardising around the various W3C
DOM specifications rather than diverging from the existing browser DOM’
s. While we have already discussed why browser manufactures are well
motivated to fake userAgent strings and offer their users a selection of
easy alternative options.

Your scenario, if taken to an extreme, may eventually negatively impact
on feature detecting as a technique. (Though scripts that used the
technique would stand up longer and better than scripts that used your
browser detecting approach.) But it is an unlikely scenario.

My scenario, of browsers offering users choices of userAgent strings
that are indistinguishable from those of other common (usually IE)
browsers (or just using those strings by default) is already a
demonstrated reality.

Richard.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,995
Messages
2,570,231
Members
46,820
Latest member
GilbertoA5

Latest Threads

Top