1

网上对浏览器类型判断多是通过 User agent 字段。但是这种方法是不可靠的,因为 User agent 很容易被修改。

下面介绍的这种判断的方法符合“鸭子类型”的风格。

鸭子类型(英语:duck typing)在程序设计中是动态类型的一种风格。在这种风格中,一个对象有效的语义,不是由继承自特定的类或实现特定的接口,而是由"当前方法和属性的集合"决定。“鸭子测试”可以这样表述:

“当看到一只鸟走起来像鸭子、游泳起来像鸭子、叫起来也像鸭子,那么这只鸟就可以被称为鸭子。”

仅在确实需要时才使用这种浏览器检测方法,例如显示特定于浏览器的安装扩展说明。尽可能使用特征检测

// Opera 8.0+
var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

// Firefox 1.0+
var isFirefox = typeof InstallTrigger !== 'undefined';

// Safari 3.0+ "[object HTMLElementConstructor]" 
var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof safari !== 'undefined' && safari.pushNotification));

// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;

// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;

// Chrome 1 - 79
var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);

// Edge (based on chromium) detection
var isEdgeChromium = isChrome && (navigator.userAgent.indexOf("Edg") != -1);

// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;


var output = 'Detecting browsers by ducktyping:<hr>';
output += 'isFirefox: ' + isFirefox + '<br>';
output += 'isChrome: ' + isChrome + '<br>';
output += 'isSafari: ' + isSafari + '<br>';
output += 'isOpera: ' + isOpera + '<br>';
output += 'isIE: ' + isIE + '<br>';
output += 'isEdge: ' + isEdge + '<br>';
output += 'isEdgeChromium: ' + isEdgeChromium + '<br>';
output += 'isBlink: ' + isBlink + '<br>';
document.body.innerHTML = output;

可靠性分析

以前的方法依赖渲染引擎的属性(-moz-box-sizing and -webkit-transform)来判断浏览器类型。这些前缀最终会被弃用。所以我转而使用更为健壮的方法——通过具体的浏览器的特性。

  • Internet Explorer:JScript 的条件编译(直至 IE9)和document.documentMode
  • Edge:在 Trident 和 Edge 浏览器中,微软提供了StyleMedia 构造函数
  • Edge (基于 chromium 内核):在 user agent 的最后,包含了这样的值:Edg/[version],如: (ex: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.16 Safari/537.36 Edg/80.0.361.9")
  • Firefox:其用于安装附加组件的API: InstallTrigger
  • Chrome: 在全局对象 chrome 中,其属性之中有一个chrome.webstore 对象。但是在最近的版本中,chrome.webstore 将会被弃用。
  • Safari:通过检查7.1版之后引入的SafariRemoteNotification,以涵盖3.0版及更高版本的 Safari。
  • Opera: window.opera 已经存在了很多年,但是将随着 Opera 将内核替换为 Blink + V8 而被弃用。

    Opera 15 中,user agent 字段更像 Chrome 的,但是额外的加入了 “OPR”。在这个本版中,chrome 对象同样被定义,但是没有 chrome.webstore。自从 Opera 开始极力克隆 Chrome 后,我便使用 user agent 来判断它。

    !!window.opr && opr.addons 仍然可以用来识别 Opera 20 以上的版本!

  • Blink: 当 Google 将 Chrome 升级至 28 版时,CSS.supports()被引入 Blink。理所当然的,同样的 Blink 也会被 Opera 使用。

测试成功的浏览器

  • Firefox 0.8 - 61
  • Chrome 1.0 - 71
  • Opera 8.0 - 34
  • Safari 3.0 - 10
  • IE 6 - 11
  • Edge - 20-42
  • Edge Dev - 80.0.361.9

刘太刚
18 声望1 粉丝