JavaScript中的浏览器检测?

233

如何使用JavaScript确定浏览器和版本信息?


确保您不要将关键功能基于此测试。 - Joe Ratzer
这里有一个更好的链接来解释对象检测:http://www.quirksmode.org/js/support.html - kmote
其他相关答案可以在这个这个重复问题中找到。 - Matthijs Wessels
25个回答

377

navigator.saysWho = (() => {
  const { userAgent } = navigator
  let match = userAgent.match(/(opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*(\d+)/i) || []
  let temp

  if (/trident/i.test(match[1])) {
    temp = /\brv[ :]+(\d+)/g.exec(userAgent) || []

    return `IE ${temp[1] || ''}`
  }

  if (match[1] === 'Chrome') {
    temp = userAgent.match(/\b(OPR|Edge)\/(\d+)/)

    if (temp !== null) {
      return temp.slice(1).join(' ').replace('OPR', 'Opera')
    }

    temp = userAgent.match(/\b(Edg)\/(\d+)/)

    if (temp !== null) {
      return temp.slice(1).join(' ').replace('Edg', 'Edge (Chromium)')
    }
  }

  match = match[2] ? [ match[1], match[2] ] : [ navigator.appName, navigator.appVersion, '-?' ]
  temp = userAgent.match(/version\/(\d+)/i)

  if (temp !== null) {
    match.splice(1, 1, temp[1])
  }

  return match.join(' ')
})()

console.log(navigator.saysWho) // outputs: `Chrome 89`

顾名思义,这将告诉您浏览器提供的名称和版本号。

当您在多个浏览器上测试新代码时,这很方便用于排序测试和错误结果。


14
我也点赞。有时候问题不在于功能支持,而是浏览器本身。是的,用户代理信息可以被伪造,但当你面对旧版本浏览器并需要规避它们的 Bug(例如 FF3 在只读 AJAX POST 消息中无法发送 Content-Length 头部的问题)时,功能支持就不足以解决问题了。 - Cobra
2
很高兴知道此函数返回的所有结果... - Diego
35
我喜欢这个!谢谢!但是,我对第一行和倒数第二行进行了修改。 我将“navigator.sayswho =”替换为“navigator.browserInfo =”,以提高可读性(即我不会在几个月后对代码的作用感到困惑),并将“return M.join(' ');”替换为“return { 'browser': M[0], 'version': M[1] };”,这样我可以在全局范围内使用它,如此:“console.log(navigator.browserInfo.browser);”和“console.log(navigator.browserInfo.version);”,以提高可访问性。抱歉,我猜我还是动了它,尽管它说“不要碰”。 - racl101
1
目前仅在Chrome上进行了测试...如果您希望获取完整的版本号,请将正则表达式更改为(vivaldi|opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([0-9|\.]+),区别在于最后一个括号不是(d+),而是([0-9|\.]+),因此包括数字和点。还添加了Vivaldi浏览器以防万一 :) - Val
3
这段代码难以阅读。tem是什么?M是什么? - kleinfreund
显示剩余14条评论

70

我建议使用小型javascript库Bowser。它基于navigator.userAgent,并且在包括iphone、android等所有浏览器中都经过了充分的测试。

https://github.com/ded/bowser

你可以简单地使用:

if (bowser.msie && bowser.version <= 6) {
  alert('Hello IE');
} else if (bowser.firefox){
  alert('Hello Foxy');
} else if (bowser.chrome){
  alert('Hello Chrome');
} else if (bowser.safari){
  alert('Hello Safari');
} else if(bowser.iphone || bowser.android){
  alert('Hello mobile');
}

33

这是我编写的用于获取客户端信息的代码

var ua = navigator.userAgent.toLowerCase();
var check = function(r) {
    return r.test(ua);
};
var DOC = document;
var isStrict = DOC.compatMode == "CSS1Compat";
var isOpera = check(/opera/);
var isChrome = check(/chrome/);
var isWebKit = check(/webkit/);
var isSafari = !isChrome && check(/safari/);
var isSafari2 = isSafari && check(/applewebkit\/4/); // unique to
// Safari 2
var isSafari3 = isSafari && check(/version\/3/);
var isSafari4 = isSafari && check(/version\/4/);
var isIE = !isOpera && check(/msie/);
var isIE7 = isIE && check(/msie 7/);
var isIE8 = isIE && check(/msie 8/);
var isIE6 = isIE && !isIE7 && !isIE8;
var isGecko = !isWebKit && check(/gecko/);
var isGecko2 = isGecko && check(/rv:1\.8/);
var isGecko3 = isGecko && check(/rv:1\.9/);
var isBorderBox = isIE && !isStrict;
var isWindows = check(/windows|win32/);
var isMac = check(/macintosh|mac os x/);
var isAir = check(/adobeair/);
var isLinux = check(/linux/);
var isSecure = /^https/i.test(window.location.protocol);
var isIE7InIE8 = isIE7 && DOC.documentMode == 7;

var jsType = '', browserType = '', browserVersion = '', osName = '';
var ua = navigator.userAgent.toLowerCase();
var check = function(r) {
    return r.test(ua);
};

if(isWindows){
    osName = 'Windows';

    if(check(/windows nt/)){
        var start = ua.indexOf('windows nt');
        var end = ua.indexOf(';', start);
        osName = ua.substring(start, end);
    }
} else {
    osName = isMac ? 'Mac' : isLinux ? 'Linux' : 'Other';
} 

if(isIE){
    browserType = 'IE';
    jsType = 'IE';

    var versionStart = ua.indexOf('msie') + 5;
    var versionEnd = ua.indexOf(';', versionStart);
    browserVersion = ua.substring(versionStart, versionEnd);

    jsType = isIE6 ? 'IE6' : isIE7 ? 'IE7' : isIE8 ? 'IE8' : 'IE';
} else if (isGecko){
    var isFF =  check(/firefox/);
    browserType = isFF ? 'Firefox' : 'Others';;
    jsType = isGecko2 ? 'Gecko2' : isGecko3 ? 'Gecko3' : 'Gecko';

    if(isFF){
        var versionStart = ua.indexOf('firefox') + 8;
        var versionEnd = ua.indexOf(' ', versionStart);
        if(versionEnd == -1){
            versionEnd = ua.length;
        }
        browserVersion = ua.substring(versionStart, versionEnd);
    }
} else if(isChrome){
    browserType = 'Chrome';
    jsType = isWebKit ? 'Web Kit' : 'Other';

    var versionStart = ua.indexOf('chrome') + 7;
    var versionEnd = ua.indexOf(' ', versionStart);
    browserVersion = ua.substring(versionStart, versionEnd);
}else{
    browserType = isOpera ? 'Opera' : isSafari ? 'Safari' : '';
}

8
总是运行所有检查,这样不觉得有点浪费吗?如果你知道它是Windows系统,那么检查Linux系统似乎没有意义,对吧? - mxk
1
@Matthias,感谢您的建议。我会尝试优化解决方案。同样的逻辑也可以应用于浏览器测试中。 - Arun P Johny
1
你的回答是任何人都能给出的最好的答案。谢谢。让我的生活变得轻松了。 - HIRA THAKUR
1
@ArunPJohny:+1,对于那些可怕的、罕见的时候,当你别无选择,只能进行浏览器检测而不是特性检测。你是否会将其更新到某个操作系统项目中?显然,自从你写下这个答案以来,IE已经停止使用MSIE了... - T.J. Crowder
2
我看到的只有 var var var var var var ...。请各位未来的程序员不要这样做。这真的没有必要,而且会让患有强迫症的项目经理感到痛苦。 - SpYk3HH
显示剩余2条评论

29

以下是2016年检测浏览器的方法,包括Microsoft Edge、Safari 10和Blink检测:

// Opera 8.0+ (UA detection to detect Blink/v8-powered Opera)
isOpera = !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;
// Firefox 1.0+
isFirefox = typeof InstallTrigger !== 'undefined';
// Safari 3.0+
isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification);
// Internet Explorer 6-11
isIE = /*@cc_on!@*/false || !!document.documentMode;
// Edge 20+
isEdge = !isIE && !!window.StyleMedia;
// Chrome 1+
isChrome = !!window.chrome && !!window.chrome.webstore;
// Blink engine detection
isBlink = (isChrome || isOpera) && !!window.CSS;
这种方法的美妙之处在于它依赖于浏览器引擎属性,因此它甚至可以覆盖那些使用主要浏览器引擎的衍生浏览器,例如Yandex或Vivaldi。唯一的例外是Opera,它依赖于用户代理嗅探,但是今天(即版本15及以上),甚至Opera本身也只是Blink的外壳。

3
这页上唯一正确的答案是:最新版本的IE之后,导航器对象已不再可靠。 - derloopkat
2
请查看此答案,以获取有关这些测试构建的文档:https://dev59.com/vGkw5IYBdhLWcg3wg6ug#9851769 - einjohn
1
@einjohn 这篇也是我写的 :D 你能分享链接真是太好了! - pilau
window.chrome.webstore 自 2018 年 06/12 起已被弃用,因此它将被评估为 false,Chrome 检测将会中断。 - Mihaly KR
@MihalyKR 谢谢,我一直在努力解决方案,很快会更新。 - pilau
此解决方案已不再适用,供您参考。 - Miguel Mota

16

在可能的情况下,最好避免使用特定于浏览器的代码。JQuery $.support 属性可用于检测对特定功能的支持,而不是依赖于浏览器名称和版本。

例如,在 Opera 中,可以模拟 Internet Explorer 或 Firefox 实例。

alt text

有关 JQuery.support 的详细说明,请参见此处: http://api.jquery.com/jQuery.support/

根据 jQuery 的说法,现在已被弃用。

我们强烈建议使用外部库,例如 Modernizr,而不是依赖于 jQuery.support 中的属性。

在编写网站时,我总是确保基本功能(如导航)也对非js用户开放。如果主页面向特定受众群体,则可以忽略此要求。


21
有时候你真的需要了解浏览器,因为同样的功能可能会以不同的方式得到支持。因此,如果使用 jQuery,$.browser 就是正确的方式,正如用户 user288744 所指出的那样。 - Bogdan D
31
有时确实需要知道浏览器版本。请确保回答被问的问题。 - Louis Chatriot
8
你没有回答问题的99%情况,而是回答了另一个问题的99%情况,你认为提问者本意或应该提出那个问题。也许先要求澄清? - Spike0xff
1
@Phil,你说得没错,有时候最好的答案是问题提问者没有想到的。然而,我不同意你将这个理论应用到这个问题上的做法。考虑window.onpopstate(请记住,在从未提到jQuery的问题中,非jQuery答案最理想)——IE不会为初始视图触发它,与其他浏览器不同。有时,为了做到健壮性,您必须考虑您正在处理的浏览器以正确实现功能。鉴于这个问题的标题,这正是人们期望的信息,而你的回答并没有提供。 - Kirk Woll
1
哦,我不想说这个,但除了为了兼容性目的使用多个浏览器测试代码之外,你还会模拟你的浏览器配置吗? - Eliseo D'Annunzio
显示剩余8条评论

12
这会告诉您有关您的浏览器及其版本的所有详细信息。
<!DOCTYPE html>
<html>
<body>
<div id="example"></div>

<script>

txt = "<p>Browser CodeName: " + navigator.appCodeName + "</p>";
txt+= "<p>Browser Name: " + navigator.appName + "</p>";
txt+= "<p>Browser Version: " + navigator.appVersion + "</p>";
txt+= "<p>Cookies Enabled: " + navigator.cookieEnabled + "</p>";
txt+= "<p>Platform: " + navigator.platform + "</p>";
txt+= "<p>User-agent header: " + navigator.userAgent + "</p>";
txt+= "<p>User-agent language: " + navigator.systemLanguage + "</p>";

document.getElementById("example").innerHTML=txt;

</script>

</body>
</html>

1
这在所有平台上都支持吗? - TheBlackBenzKid
3
看起来我的所有浏览器都是网景浏览器。要么你的代码有问题,要么我在迷幻中。 - erdomester
@erdomester 显然其他人也成功了......对我也起作用。 - malcolmX
6
“在我的机器上可以运行”不是Web开发的可接受方式。 - OZ_
1
这些方法已经过时,不应再使用。 - Levi Morrison
显示剩余3条评论

7
//Copy and paste this into your code/text editor, and try it

//Before you use this to fix compatability bugs, it's best to try inform the browser provider that you have found a bug and there latest browser may not be up to date with the current web standards

//Since none of the browsers use the browser identification system properly you need to do something a bit like this

//Write browser identification
document.write(navigator.userAgent + "<br>")

//Detect browser and write the corresponding name
if (navigator.userAgent.search("MSIE") >= 0){
    document.write('"MS Internet Explorer ');
    var position = navigator.userAgent.search("MSIE") + 5;
    var end = navigator.userAgent.search("; Windows");
    var version = navigator.userAgent.substring(position,end);
    document.write(version + '"');
}
else if (navigator.userAgent.search("Chrome") >= 0){
document.write('"Google Chrome ');// For some reason in the browser identification Chrome contains the word "Safari" so when detecting for Safari you need to include Not Chrome
    var position = navigator.userAgent.search("Chrome") + 7;
    var end = navigator.userAgent.search(" Safari");
    var version = navigator.userAgent.substring(position,end);
    document.write(version + '"');
}
else if (navigator.userAgent.search("Firefox") >= 0){
    document.write('"Mozilla Firefox ');
    var position = navigator.userAgent.search("Firefox") + 8;
    var version = navigator.userAgent.substring(position);
    document.write(version + '"');
}
else if (navigator.userAgent.search("Safari") >= 0 && navigator.userAgent.search("Chrome") < 0){//<< Here
    document.write('"Apple Safari ');
    var position = navigator.userAgent.search("Version") + 8;
    var end = navigator.userAgent.search(" Safari");
    var version = navigator.userAgent.substring(position,end);
    document.write(version + '"');
}
else if (navigator.userAgent.search("Opera") >= 0){
    document.write('"Opera ');
    var position = navigator.userAgent.search("Version") + 8;
    var version = navigator.userAgent.substring(position);
    document.write(version + '"');
}
else{
    document.write('"Other"');
}

//Use w3schools research the `search()` method as other methods are availible

7
请勿推荐w3schools。 - iConnor
1
就像其他数十亿个代码片段一样,这个在IE 11(以及后续版本)上失败了。 - Spike0xff
在Chrome中出现“未定义”错误。 - OZ_

7

关于 web 浏览器的所有信息都包含在导航对象中。名称和版本都在其中。

var appname = window.navigator.appName;

来源:JavaScript浏览器检测


35
Chrome说“Netscape”。 - Incognito
4
Firefox 20.0.1在XP上也显示“Netscape”。 - Metalcoder
2
Firefox和Chrome显示“Netscape”。IE 8什么也不显示! - Patrick Keane
尝试使用appcodename:http://www.w3schools.com/jsref/prop_nav_appcodename.asp - George
3
在 Chrome 33 中,appCodeName 是 Mozilla,appName 是 Netscape。 - Natwar Singh

6
自从Internet Explorer 11(IE11+)发布以来,不再使用MSIE标签名称,因此我想到了一种旧的检测函数的变体:
navigator.sayswho= (function(){
    var N= navigator.appName, ua= navigator.userAgent, tem;

    // if IE11+
    if (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(ua) !== null) {
        var M= ["Internet Explorer"];
        if(M && (tem= ua.match(/rv:([0-9]{1,}[\.0-9]{0,})/))!= null) M[2]= tem[1];
        M= M? [M[0], M[2]]: [N, navigator.appVersion,'-?'];
        return M;
    }

    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;
})();

5

可悲的是,IE11在其navigator.userAgent中不再包含MSIE

Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0; OfficeLiveConnector.1.5; OfficeLivePatch.1.3; .NET4.0C; BRI/2; BOIE9;ENUS; rv:11.0) like Gecko

你想知道你使用的是哪个浏览器,是因为每个浏览器都有自己的一套缺陷,这就导致你必须实现特定于浏览器和版本的解决方案,或者告诉用户使用另一个浏览器!


这就是人们使用它的目的。如果他们知道不支持IE,请检测并让他们知道。 - user6031759

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接