0

Reasoning for this Question

I am aware that browser detection can never be 100% reliable as the User Agent header can always be forged, however, I am not bothered by this.

Although there are many questions on this topic, they all seem to be quite old, so to get an up to date answer I felt I should ask this question again.

I am currently detecting the browser name and version server side using the PHP browscap, and then returning the name and version into javascript variables (not a very good method). The reason why I need to do this is simply to display a message to visitors if they are not using a supported browser.

Current method (something similar):

<script type="text/javascript">
    var browser = new Array();
    browser['browser'] = '<?php echo $browser_name; ?>';
    browser['version'] = '<?php echo $browser_version; ?>';
    browser['error'] = '<?php echo $browser_error; ?>';
</script>

It would be much better to do this client side as the browscap can be quite slow, and it would prevent me having to pass values into javascript variables from PHP. If you think using PHP is a better method then please state in your answer, this is just my opinion.

Question

Therefore, my question quite simply, is the following link a reliable method for determining the browser name and version?

Javascript Detect

I am aware that new browsers will need to be added to this, this does not bother me. I am more concerned about whether the algorithm used is reliable.

Thanks in advance

UPDATE 1

To see what I mean, take a look at https://www.icloud.com/ in Internet Explorer 7 or less. You will receive a message saying that the browser is not supported. This is easy to do for IE as you can simply use the <!--[if gt IE..., however, I need to test all browsers.

Ben Carey
  • 16,540
  • 19
  • 87
  • 169
  • have a look at media queries also – Arun Killu Oct 29 '12 at 12:09
  • 1
    So why are you browser sniffing again? – Asad Saeeduddin Oct 29 '12 at 12:11
  • @Asad because certain things do not work in particular browsers, e.g. images with an transparent background in Internet Explorer 7 and down, do not animate well using jQuery. One of many examples – Ben Carey Oct 29 '12 at 12:12
  • Your script can find directly whether this feature is present in the browser using js, and respond appropriately. This is called feature detection, and is superior to browser sniffing for a [slew of reasons](https://developer.mozilla.org/en-US/docs/Browser_Detection_and_Cross_Browser_Support). Have a look at Modernizr. – Asad Saeeduddin Oct 29 '12 at 12:15
  • @Asad Okay, for example. How would I detect whether images with a transparent background can be animated without looking awful?? You can only test for the opacity feature surely? – Ben Carey Oct 29 '12 at 12:17
  • You need to have a more technical description of the problem than "looking awful". If you can identify what the missing feature is, you'll know to look out for it. – Asad Saeeduddin Oct 29 '12 at 12:18
  • @Asad Not sure how I can explain this particular one, but if you apply `filter:alpha(opacity=50);` to a background image on an HTML page in IE 7 or less, teh background goes black instead of transparent. Dont think there is a feature to point this out – Ben Carey Oct 29 '12 at 12:22
  • Have you tried including `-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=50)";` first? – Asad Saeeduddin Oct 29 '12 at 12:25
  • @Asad The opacity works, but it makes the transparent part go black – Ben Carey Oct 29 '12 at 12:27
  • After some googling, I found [this](http://viget.com/inspire/jquery-ie-png-24-ie-black-background-issue-solved). Same issue as you, css fix. – Asad Saeeduddin Oct 29 '12 at 12:35
  • @Asad That is a very good fix, thank you1 :-) However, this just fixes one feature that I wanted to detect. I still need to detect the browser name and version – Ben Carey Oct 29 '12 at 13:34
  • @BenCarey *sigh*, alright. But have a look at feature detection when you can. The problem with browser detection is that your code is not forward compatible. Every time they make a new browser you need to add a check for it and add an appropriate set of fallbacks/polyfills etc. – Asad Saeeduddin Oct 29 '12 at 13:36
  • @Asad I know :-( I think I will look to find another way to do this that prevents the need for browser detection – Ben Carey Oct 29 '12 at 13:54

6 Answers6

1

This does not look right, you can fetch browser information from Javascript. No need to mix JS and PHP code to do that.

You can do something like this to fetch, and detect user browser with just JavaScript:

var userAgent = navigator.userAgent.toLowerCase();
var old = false;

// Internet Explorer 7
if (userAgent.indexOf('msie 7.0b') !== -1) { old = true; }
else if (userAgent.indexOf('msie 7.0') !== -1) { old = true; }

// Internet Explorer 6
else if (userAgent.indexOf('msie 6.1') !== -1) { old = true; }
else if (userAgent.indexOf('msie 6.01') !== -1) { old = true; }
else if (userAgent.indexOf('msie 6.0b') !== -1) { old = true; }
else if (userAgent.indexOf('msie 6.0') !== -1) { old = true; }
...
// Detect any other browser versions you consider old

if(old = true) {
// Show notification and alert users that they are using old browser
}

This is how you can do it using JS, but you can also use HTML to achieve this:

<!--[if lte IE 6]>
   // include your .css style or do whatever you want to alert users their browser is old
<![endif]-->

Short answer to your question is YES, its wrong to detect user browser the way you do it, since you can do it with plain JavaScript, or even with HTML. No need to mix PHP and JS code here, and at the end, both PHP and JS will get the same UserAgent info.

otporan
  • 1,345
  • 2
  • 12
  • 29
  • This is quite a long winded method as you have to list every possible browser, surely my link is better than this? The PHP script that I use is extremely reliable as it is updated daily from Gary Keiths website: https://browsers.garykeith.com/downloads – Ben Carey Oct 29 '12 at 12:19
  • My JS example is not the best way to detect browser, but its just something to get you going if you are looking to write your own client side Browser detector. And any other library or plugin will do the same thing, compare current client with the ones you dont want. The best way to detect browser is to do it in Client, using JS. So the way to go is to find some JS Browser detector, or some of the jQuery plugins to detect browser. No need to mix PHP with JS really. Or you can use example with HTML that lots of people use, the simplest way to detect browsers older then IE6, and notify them. – otporan Oct 29 '12 at 12:24
  • That is why I posted this link! http://www.quirksmode.org/js/detect.html I wanted to know if it was reliable enough – Ben Carey Oct 29 '12 at 12:25
1

Explanation

After extensive research and discussing amongst other developers, it is clear that there is no reliable method for retrieving the browser name and version from the User Agent. This is down to several reasons:

  1. The format of a browsers User Agent can change at any time if the developers of the browser so wish to do so. This could immediately prevent some scripts from working correctly.
  2. Users can forge their User Agents to mimic other browsers, and therefore would appear to be using a browser they are not.

Possible Solutions

Whilst I hugely discourage the use of these scripts as they could stop working at the release of an update to any browser anytime, if you do wish to detect the browser name and version in Javascript then I would advise using this script:

Javascript Detect

However, the most reliable method for retrieving the details of the browser is without a doubt the browscap supplied by Gary Keith. The browscap project offers extensive information about each browser and OS gathered from the User Agent. It is very easy to implement and even easier to use. To read more, take a look at:

Gary Keith - Browscap

If you choose to use the browscap by Gary Keith, you will need to ensure it is updated weekly at the very least.

Answer

Whilst I am contradicting myself with this answer, it is clear that detecting the browser information with any sort of script is not advised. The only reliable method of browser detection is that of the Internet Explorer HTML conditions, and as stated, these only cover Internet Explorer.

Try to avoid browser specific functions and notices, and make use of the built in features such as:

media="only screen and (device-width: 768px)"

and

<!--[if IE 8]>I am IE 8<![endif]-->
Ben Carey
  • 16,540
  • 19
  • 87
  • 169
1

This question needs an updated answer. I think the best option these days for client-side detection is WURFL.

Its an updated library of devices based on Useragents - think Browscap for the client side.

Load the JS and it returns JSON based on the device that requested the js. Perfect!

<script type="text/javascript" src="//wurfl.io/wurfl.js"></script>

Because it does the parsing on the WURFL server side, you need to load the js remotely and not save it in your dir tree.

A super easy

WURFL.is_mobile

is all it takes to determine mobile for example.

Good luck.

Christian
  • 3,917
  • 2
  • 23
  • 40
0

You could try having a look at navigator.appName and navigator.userAgent.

EM-Creations
  • 4,195
  • 4
  • 40
  • 56
0

The yepnopejs IE detection (!ie prefixes) works by utilizing the MS conditional comments.

A short snippet for detecting versions of IE prior to IE10 in JavaScript without resorting to user-agent sniffing.

while (
  div.innerHTML = '<!--[if gt IE ' + (++v) + ']><i></i><![endif]-->'
);
// …

https://github.com/SlexAxton/yepnope.js/blob/master/prefixes/yepnope.ie-prefix.js

yepnope usage example:

yepnope({
    load: ['normal.js', 'ie6!ie7!ie-patch.js'] // patch for ie6 or ie7 only
});
feeela
  • 29,399
  • 7
  • 59
  • 71
-1

You can use a perfect plugin for this information written in jQuery (like javascript)

look at this link:

https://github.com/jquery/plugins.jquery.com

Be sure to do feature detection instead of browser detection when you want to determine if a certain feature is available in a browser, apply bugfixes, etc.

Alessandro Minoccheri
  • 35,521
  • 22
  • 122
  • 171