我有5个插件/扩展用于FF、Chrome、IE、Opera和Safari.

如何识别用户浏览器并重定向(单击安装按钮后)以下载相应的插件?

推荐答案

Googling for browser reliable detection often results in checking the User agent string. This method is not reliable, because it's trivial to spoof this value.
I've written a method to detect browsers by duck-typing.

仅在确实必要时使用浏览器检测方法,例如显示特定于浏览器的安装扩展说明.Use feature detection when possible.

演示:https://jsfiddle.net/6spj1059/

// 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' && window['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;

可靠性分析

previous method取决于渲染引擎(-moz-box-sizing-webkit-transform)的属性来检测浏览器.这些前缀最终将被删除,因此为了使检测更加可靠,我切换到浏览器特定的特征:

  • Internet Explorer:JScript的Conditional compilation(直到IE9)和document.documentMode.
  • Edge:在三叉戟和Edge浏览器中,Microsoft的实现公开了StyleMedia构造函数.除go 三叉戟,我们只剩下边缘.
  • Edge(基于Chrome):用户代理在末尾包含值"Edg/[version]"(例如:"Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,比如Gecko)Chrome/80.0.3987.16 Safari/537.36 Edg/80.0.361.9").
  • Firefox:Firefox安装附加组件的API:InstallTrigger
  • Chrome:全局chrome对象,包含多个属性,包括一个记录在案的chrome.webstore对象.
  • 更新3 chrome.webstore在最近的版本中已弃用且未定义
  • Safari:一种独特的构造函数命名模式.这是所有列出的属性中最不持久的方法,你猜怎么着?在Safari 9.1.3中,它是固定的.因此,我们正在对照版本7.1之后引入的SafariRemoteNotification,以涵盖3.0及以上的所有Safaris.
  • Opera:window.opera已经存在多年了,但当Opera用Blink+V8(Chromium使用)取代引擎时,它就变成了will be dropped.
  • 更新1:Opera 15 has been released,它的UA字符串看起来像Chrome,但增加了"opr".在这个版本中,定义了chrome对象(但chrome.webstore没有).由于Opera试图克隆Chrome,为此我使用了用户代理嗅探.
  • 更新2:!!window.opr && opr.addons可用于检测Opera 20+(常青树).
  • blink :谷歌打开Chrome 28后,CSS.supports() was introduced in Blink.当然,这和歌剧中的 blink 是一样的.

已在以下位置成功测试:

  • firefox 0.8-61
  • chromium 1.0-71
  • 歌剧8.0-34
  • Safari 3.0-10
  • IE 6-11
  • 边缘-20-42
  • 边缘设备-80.0.361.9

2016年11月更新,包括检测9.1.3及以上版本的Safari浏览器

更新于2018年8月,更新了对Chrome、Firefox IE和EDGE的最新成功测试.

2019年1月更新,以修复chrome检测(因为window.chrome.webstore遭到弃用),并包括最新的chrome成功测试.

2019年12月更新,添加了基于 chromium 检测的边缘(基于@Nimesh comments ).

Javascript相关问答推荐

脚本.js:3:20未捕获的类型错误:无法读取空的属性(读取addEventHandler)

有Angular 的material .未应用收件箱中的价值变化

在nextjs服务器端api调用中传递认证凭证

将现场录音发送到后端

未捕获错误:[]:getActivePinia()被调用,但没有活动Pinia.🍍""在调用app.use(pinia)之前,您是否try 使用store ?""

如果Arrow函数返回函数,而不是为useEffect返回NULL,则会出现错误

我在Django中的视图中遇到多值键错误

是什么导致了这种奇怪的水平间距错误(?)当通过JavaScript将列表项元素追加到无序列表时,是否在按钮之间?

try 使用PM2在AWS ubuntu服务器上运行 node 进程时出错

如何限制显示在分页中的可见页面的数量

我想将Sitecore搜索面过滤器从多个转换为单个

Docent.cloneNode(TRUE)不克隆用户输入

如何根据输入数量正确显示alert ?

我正在试着做一个TicTacToe Ai来和我玩.但是,我试着在第一个方块被点击时出现一个X,然后在第二个方块之后出现一个O

使用Reaction窗体挂钩注册日历组件

如何让SVG图标在被点击和访问后改变 colored颜色 ,并在被访问后取消点击时恢复到原来的 colored颜色 ?

如何正确地在ComponentWillUnmount中卸载状态以避免内存泄漏?

JQuery使用选项填充HTMLSELECT并设置默认结果,默认结果显示为空

在范围数组中查找公共(包含)范围

使用VITE开发服务器处理错误