JavaScript 中的浏览器检测?

IT技术 javascript browser-detection
2021-02-04 09:19:08

如何使用 JavaScript 确定确切的浏览器和版本?

6个回答

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`

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

当您在多个浏览器上测试新代码时,它可以方便地对测试和错误结果进行排序。

很高兴知道这个函数返回的所有结果......
2021-03-12 09:19:08
+1也来自我。有时,这与功能支持无关,而实际上与浏览器有关。是的,用户代理信息可以被欺骗,但是当您处理较旧的浏览器并规避它们的错误时(例如 FF 3 不发送只读 AJAX POST 消息的 Content-Length 标头的问题),功能支持就不会不剪。
2021-03-21 09:19:08
我喜欢这个!谢啦!不过,我只是对第一行和倒数第二行进行了修改。在第一行替换了:navigator.sayswho=withnavigator.browserInfo=以获得更好的可读性(即,我不会怀疑几个月后它在代码中的作用)并替换为return M.join(' ');return { 'browser': M[0], 'version': M[1] };以便我可以在全局范围内像这样使用它:console.log(navigator.browserInfo.browser);console.log(navigator.browserInfo.version);获得更好的可访问性。对不起,我想我确实把它弄乱了,即使它说“不要碰”。
2021-03-22 09:19:08
这段代码几乎不可读。什么是tem什么是M
2021-03-25 09:19:08
暂时只在 chrome 上测试过......如果你想获得完整的版本号,将 regx 更改为(vivaldi|opera|chrome|safari|firefox|msie|trident(?=\/))\/?\s*([0-9|\.]+)差异是最后一个括号而不是(d+)它应该是([0-9|\.]+)数字和点。还添加了 vivaldi 浏览器以防万一:)
2021-04-09 09:19:08

我建议使用微型 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');
}

这是我为了获取客户信息而写的

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' : '';
}
@Matthias,感谢您的建议。我会尝试优化解决方案。同样的逻辑也可以应用于浏览器的测试。
2021-03-21 09:19:08
总是运行所有检查是不是有点浪费?如果您知道它是 Windows,那么检查 Linux 似乎毫无意义,不是吗...
2021-03-24 09:19:08
我所看到的只是var var var var var var ...拜托,看到这一点的未来编码员,不要这样做。这真的没有必要,而且对于患有强迫症的项目经理来说阅读起来很痛苦。
2021-03-26 09:19:08
@ArunPJohny:+1,对于那些您别无选择只能进行浏览器检测而不是功能检测的可怕的、罕见的情况。您是否保持最新状态,也许在某个操作系统项目中?显然,自从你写了这个答案后,IE 就不再说 MSIE 了……
2021-04-04 09:19:08
你的答案是任何人都可以给出的最佳答案..thx.让我的生活变得轻松
2021-04-07 09:19:08

以下是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 的外壳。

此页面中唯一正确的答案。在最新的 IE 版本之后,导航器对象不再可靠。
2021-03-25 09:19:08
@einjohn 也是我写的 :D 很高兴你能链接!
2021-03-26 09:19:08
查看其他答案以获取有关这些测试所基于内容的文档:stackoverflow.com/a/9851769/726097
2021-03-27 09:19:08
window.chrome.webstore 自 2018 年 6 月 12 日起已弃用,因此它将评估为 false 并且 chrome 检测将中断。
2021-03-29 09:19:08
@MihalyKR 谢谢,我一直在研究解决方案,很快就会更新。
2021-04-06 09:19:08

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

例如,在 Opera 中,您可以伪造 Internet Explorer 或 firefox 实例。

替代文字

JQuery.support 的详细描述可以在这里找到:http ://api.jquery.com/jQuery.support/

现在已根据 jQuery 弃用。

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

在编写网站时,我总是确保非 js 用户也可以访问导航等基本功能。这可能会成为讨论的对象,如果主页面向特殊受众,则可以忽略。

@Phil,您是对的,有时最好的答案是提问者甚至没有问过的答案。但是,我不同意您将该理论应用于这个问题。考虑一下window.onpopstate(并且请记住,对于从未提及 jQuery 的问题,非 jQuery 答案是最理想的)——与其他浏览器相比,IE 不会为初始视图触发它。有时,为了健壮,您必须考虑您正在处理的浏览器以正确实现功能。鉴于此问题的标题,这正是人们所期望的信息,而您的则不然。
2021-03-19 09:19:08
有时您确实需要知道浏览器版本。请务必回答所提出的问题。
2021-03-27 09:19:08
@PhilRykoff - 但你没有回答问题的 99% 情况 - 你正在回答另一个问题的 99% 情况,你认为提问者打算问,或者应该问。也许先要求澄清?
2021-03-29 09:19:08
呃,我不想这么说,但是除了出于兼容性目的使用多个浏览器测试您的代码之外,您还会欺骗浏览器的配置吗?
2021-03-30 09:19:08
有时您真的需要了解浏览器,而当以不同的方式支持相同的功能时。所以,如果使用 jQuery,$.browser 是正确的方法,如 user288744 所示
2021-04-09 09:19:08