What is a RELIABLE way to detect a client's br

2019-01-29 04:51发布

问题:

What is a reliable way to detect someone's browser and its version number? From what I've seen, things like the navigator object in JavaScript simply do not work toward this end, and neither do a lot of these really hacked-together solutions I'm coming across. There are one or two currently functional JavaScript code snippets I've come across that'll tell me whether someone is using Firefox, Chrome, etc., but they don't describe the version number of each browser. How can this be found, and how can it be done reliably? (The front-ends are a couple of Flex applications.)

EDIT

This question has been linked to a very similar one, with the suggestion that I should be able to just use the answer there. I can't; it doesn't work for unknown reasons. In my earlier edit, the one below this, the first example I post is from that other question. Please remove this link. Thanks.

EDIT

I know this question has been asked a million times, but the answers I'm coming across, including accepted ones on Stack Overflow, either just do not work or do not work well enough to be used. That's why I'm emphasizing the word "reliable". One thing that's getting in the way is that in a lot of code snippets, you'll see "Netscape" come up instead of "Internet Explorer", etc.

For example, "Internet Explorer 11", "Firefox 26", etc. Or at least something kind of close to that.

Here are some examples of code snippets that aren't working out too well:

Popular, but it won't run when I try it:

navigator.sayswho= (function(){
    var ua= navigator.userAgent, tem, 
    M= ua.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([\d\.]+)/i) || [];
    if(/trident/i.test(M[1])){
        tem=  /\brv[ :]+(\d+(\.\d+)?)/g.exec(ua) || [];
        return 'IE '+(tem[1] || '');
    }
    M= M[2]? [M[1], M[2]]:[navigator.appName, navigator.appVersion, '-?'];
    if((tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
    return M.join(' ');
})();

Works great with Firefox, but says IE is Netscape and gives very complicated results when describing the version:

function get_browser(){
    var N=navigator.appName, ua=navigator.userAgent, tem;
    var M=ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
    if(M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
    M=M? [M[1], M[2]]: [N, navigator.appVersion, '-?'];
    return M[0];
}
function get_browser_version(){
    var N=navigator.appName, ua=navigator.userAgent, tem;
    var M=ua.match(/(opera|chrome|safari|firefox|msie)\/?\s*(\.?\d+(\.\d+)*)/i);
    if(M && (tem= ua.match(/version\/([\.\d]+)/i))!= null) M[2]= tem[1];
    M=M? [M[1], M[2]]: [N, navigator.appVersion, '-?'];
    return M[1];
}

alert(get_browser())
alert(get_browser_version())

This is almost what I need; as long as it doesn't require the newest version of anything, then I just need version numbers as well:

var isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
// Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
var isFirefox = typeof InstallTrigger !== 'undefined';   // Firefox 1.0+
var isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
// At least Safari 3+: "[object HTMLElementConstructor]"
var isChrome = !!window.chrome && !isOpera;              // Chrome 1+
var isIE = /*@cc_on!@*/false || !!document.documentMode; // At least IE6

Something that gives a string back like:

Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko

for IE11 or calls Firefox and IE "Netscape" isn't quite what I'm looking for. The navigator object in JavaScript has a lot of issues with this sort of thing.

回答1:

There is no reliable way to perform browser sniffing. My best suggestion would be to take a look at WhichBrowser - the power behing http://html5test.com/

Everybody lies — House M.D.

This is a extremely complicated and almost completely useless browser sniffing library. Useless because you shouldn't use browser sniffing. So stop right now and go read something about feature detecting instead. I'm serious. Go away. You'll thank me later.

But why almost completely useless and not completely useless?

Well, there is always an exception to the rule. There is one valid reason to do browser sniffing: to gather intelligence about which browsers are used on your website. My website is html5test.com and I wanted to know which score belongs to which browser. And to do that you need a browser sniffing library.

Why is it extremely complicated?

Because everybody lies. Seriously, there is not a single browser that is completely truthful. Almost all browsers say they are Netscape 5 and almost all WebKit browsers say they are based on Gecko. Even Internet Explorer 11 now no longer claims to be IE at all, but instead an unnamed browser that is like Gecko. And it gets worse. That is why it is complicated.

The main part of this library runs on the server and looks at the headers send by the browser, but it also collects various data from the browser itself. The first thing it looks at is the user-agent header, but there are many more headers that contain clues about the identity of the browser. Once the server finds the identity of the browser, it then looks at the data from the browser itself and check some additional characteristics and tries to determine if the headers where perhaps lying. It then gives you the result.

Notes on install/requirements

How to install it

Place the files in a directory on your server. The server should be able to handle PHP and included is a .htaccess file that instructs the server to also use PHP to parse the detect.js file. This is required and if your server does not support .htaccess files you need to find a way to make your server do the same.

Notes to help you with getting it working on IIS rather than apache

Translate .htaccess Content to IIS web.config

If you get it working on IIS then you may want to post some further notes on how to achieve this.