我有5个适用于Firefox、Chrome、Internet Explorer(IE)、Opera和Safari的插件/扩展程序。
当用户单击“安装”按钮后,如何正确识别用户的浏览器并重定向到下载相应的插件?
我有5个适用于Firefox、Chrome、Internet Explorer(IE)、Opera和Safari的插件/扩展程序。
当用户单击“安装”按钮后,如何正确识别用户的浏览器并重定向到下载相应的插件?
// 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;
先前的方法依赖于渲染引擎的属性(-moz-box-sizing
和 -webkit-transform
)来检测浏览器。这些前缀最终会被弃用,因此为了使检测更加稳健,我转而使用浏览器特定的特征:
document.documentMode
。StyleMedia
构造函数。排除Trident后我们得到Edge。InstallTrigger
chrome
对象,包含多个属性,包括文档化的chrome.webstore
对象。chrome.webstore
已弃用并在最新版本中未定义SafariRemoteNotification
,它在版本7.1之后引入,以覆盖从3.0及以上的所有Safari。window.opera
已存在多年,但是当Opera将其引擎替换为Blink + V8(由Chromium使用)时,将被删除。
chrome
对象(但未定义chrome.webstore
)。由于Opera努力克隆Chrome,因此我使用用户代理嗅探来实现此目的。!!window.opr && opr.addons
可用于检测Opera 20+(常青)。CSS.supports()
在Google切换Chrome 28时引入Blink。当然,这与Opera中使用的相同Blink。更新于2016年11月,包括检测Safari浏览器版本9.1.3及以上
更新于2018年8月,更新了对chrome、firefox、IE和edge的最新成功测试。
更新于2019年1月,修复了chrome检测问题(因为window.chrome.webstore已被弃用),并包含chrome的最新成功测试。
更新于2019年12月,添加基于Chromium的Edge浏览器检测(基于@Nimesh评论)。
window.chrome.webstore
未定义。尚未使用Firefox扩展进行检查。在其他地方提到的is.js
可以在Chrome和Firefox扩展中使用。 - nevfisSafari
在 Safari 10 中无法使用。我认为这是一个不好的解决方案(虽然我没有更好的解决方案)。不能保证你检查的许多东西不会被其他浏览器删除或添加。所有使用此代码来检查 Safari 的网站在升级到 macOS Sierra 或 Safari 10 后都将出现问题 :( - gmanisSafari
在 Safari 10.1.2 的 <iframe>
下无法工作。 - Mikko Ohtamaa你可以尝试以下方法来检查浏览器版本。
<!DOCTYPE html>
<html>
<body>
<p>What is the name(s) of your browser?</p>
<button onclick="myFunction()">Try it</button>
<p id="demo"></p>
<script>
function myFunction() {
if((navigator.userAgent.indexOf("Opera") || navigator.userAgent.indexOf('OPR')) != -1 )
{
alert('Opera');
}
else if(navigator.userAgent.indexOf("Edg") != -1 )
{
alert('Edge');
}
else if(navigator.userAgent.indexOf("Chrome") != -1 )
{
alert('Chrome');
}
else if(navigator.userAgent.indexOf("Safari") != -1)
{
alert('Safari');
}
else if(navigator.userAgent.indexOf("Firefox") != -1 )
{
alert('Firefox');
}
else if((navigator.userAgent.indexOf("MSIE") != -1 ) || (!!document.documentMode == true )) //IF IE > 10
{
alert('IE');
}
else
{
alert('unknown');
}
}
</script>
</body>
</html>
如果你只需要知道IE浏览器的版本,可以按照下面的代码进行操作。此代码适用于IE6到IE11版本。
<!DOCTYPE html>
<html>
<body>
<p>Click on Try button to check IE Browser version.</p>
<button onclick="getInternetExplorerVersion()">Try it</button>
<p id="demo"></p>
<script>
function getInternetExplorerVersion() {
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
var rv = -1;
if (msie > 0 || !!navigator.userAgent.match(/Trident.*rv\:11\./)) // If Internet Explorer, return version number
{
if (isNaN(parseInt(ua.substring(msie + 5, ua.indexOf(".", msie))))) {
//For IE 11 >
if (navigator.appName == 'Netscape') {
var ua = navigator.userAgent;
var re = new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})");
if (re.exec(ua) != null) {
rv = parseFloat(RegExp.$1);
alert(rv);
}
}
else {
alert('otherbrowser');
}
}
else {
//For < IE11
alert(parseInt(ua.substring(msie + 5, ua.indexOf(".", msie))));
}
return false;
}}
</script>
</body>
</html>
chrome
关键词。例如 Safari 的用户代理:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_5) AppleWebKit/601.6.17 (KHTML, like Gecko) Version/9.1.1 Safari/601.6.17
。 - Golak Sarangiif(navigator.userAgent.indexOf("Opera") != -1 || navigator.userAgent.indexOf('OPR') != -1 )
。 - Kyle Vassella以下是2019年12月的几个处理浏览器检测的著名库。
var result = bowser.getParser(window.navigator.userAgent);
console.log(result);
document.write("You are using " + result.parsedResult.browser.name +
" v" + result.parsedResult.browser.version +
" on " + result.parsedResult.os.name);
<script src="https://unpkg.com/bowser@2.7.0/es5.js"></script>
*支持基于Chromium的Edge浏览器
console.log(platform);
document.write("You are using " + platform.name +
" v" + platform.version +
" on " + platform.os);
<script src="https://cdnjs.cloudflare.com/ajax/libs/platform/1.3.5/platform.min.js"></script>
console.log($.browser)
document.write("You are using " + $.browser.name +
" v" + $.browser.versionNumber +
" on " + $.browser.platform);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-browser/0.1.0/jquery.browser.min.js"></script>
var result = detect.parse(navigator.userAgent);
console.log(result);
document.write("You are using " + result.browser.family +
" v" + result.browser.version +
" on " + result.os.family);
<script src="https://cdnjs.cloudflare.com/ajax/libs/Detect.js/2.2.2/detect.min.js"></script>
console.log(BrowserDetect)
document.write("You are using " + BrowserDetect.browser +
" v" + BrowserDetect.version +
" on " + BrowserDetect.OS);
<script src="https://kylemit.github.io/libraries/libraries/BrowserDetect.js"></script>
我知道为此使用一个库可能过于冗长,但只是为了丰富这个话题,你可以查看is.js的做法:
is.firefox();
is.ie(6);
is.not.safari();
is.js
的源代码并查看他们是如何做到的。 - Rafael Eyng短变量 (2020年7月10日更新移动浏览器检测修复)
var browser = (function() {
var test = function(regexp) {return regexp.test(window.navigator.userAgent)}
switch (true) {
case test(/edg/i): return "Microsoft Edge";
case test(/trident/i): return "Microsoft Internet Explorer";
case test(/firefox|fxios/i): return "Mozilla Firefox";
case test(/opr\//i): return "Opera";
case test(/ucbrowser/i): return "UC Browser";
case test(/samsungbrowser/i): return "Samsung Browser";
case test(/chrome|chromium|crios/i): return "Google Chrome";
case test(/safari/i): return "Apple Safari";
default: return "Other";
}
})();
console.log(browser)
Typescript 版本:
export enum BROWSER_ENUM {
EDGE ,
INTERNET_EXPLORER ,
FIRE_FOX ,
OPERA ,
UC_BROWSER ,
SAMSUNG_BROWSER ,
CHROME ,
SAFARI ,
UNKNOWN ,
}
const testUserAgent = (regexp: RegExp): boolean => regexp.test(window.navigator.userAgent);
function detectBrowser(): BROWSER_ENUM {
switch (true) {
case testUserAgent(/edg/i): return BROWSER_ENUM.EDGE;
case testUserAgent(/trident/i): return BROWSER_ENUM.INTERNET_EXPLORER;
case testUserAgent(/firefox|fxios/i): return BROWSER_ENUM.FIRE_FOX;
case testUserAgent(/opr\//i): return BROWSER_ENUM.OPERA;
case testUserAgent(/ucbrowser/i): return BROWSER_ENUM.UC_BROWSER;
case testUserAgent(/samsungbrowser/i): return BROWSER_ENUM.SAMSUNG_BROWSER;
case testUserAgent(/chrome|chromium|crios/i): return BROWSER_ENUM.CHROME;
case testUserAgent(/safari/i): return BROWSER_ENUM.SAFARI;
default: return BROWSER_ENUM.UNKNOWN;
}
}
export const BROWSER: BROWSER_ENUM = detectBrowser();
export const IS_FIREFOX = BROWSER === BROWSER_ENUM.FIRE_FOX;
纯属娱乐的函数式算法:
var BROWSER = new Array(
["Microsoft Edge", /edg/i],
["Microsoft Internet Explorer", /trident/i],
["Mozilla Firefox", /firefox|fxios/i],
["Opera", /opr\//i],
["UC Browser", /ucbrowser/i],
["Samsung Browser", /samsungbrowser/i],
["Google Chrome", /chrome|chromium|crios/i],
["Apple Safari", /safari/i],
["Unknown", /.+/i],
).find(([, value]) => value.test(window.navigator.userAgent)).shift();
如果有人发现这个有用,我已经将Rob W的答案制成了一个函数,该函数返回浏览器字符串而不是让多个变量漂浮。由于浏览器也不能真正地在没有重新加载的情况下更改,因此我将其缓存结果以防止需要再次计算函数调用时的结果。
/**
* Gets the browser name or returns an empty string if unknown.
* This function also caches the result to provide for any
* future calls this function has.
*
* @returns {string}
*/
var browser = function() {
// Return cached result if avalible, else get result then cache it.
if (browser.prototype._cachedResult)
return browser.prototype._cachedResult;
// 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'] || safari.pushNotification);
// Internet Explorer 6-11
var isIE = /*@cc_on!@*/false || !!document.documentMode;
// Edge 20+
var isEdge = !isIE && !!window.StyleMedia;
// Chrome 1+
var isChrome = !!window.chrome && !!window.chrome.webstore;
// Blink engine detection
var isBlink = (isChrome || isOpera) && !!window.CSS;
return browser.prototype._cachedResult =
isOpera ? 'Opera' :
isFirefox ? 'Firefox' :
isSafari ? 'Safari' :
isChrome ? 'Chrome' :
isIE ? 'IE' :
isEdge ? 'Edge' :
isBlink ? 'Blink' :
"Don't know";
};
console.log(browser());
window.chrome.webstore
,因此这种方法不再可用。 - Bedla我不知道这是否对任何人有用,但这是一个可以让TypeScript满意的变体:
export function getBrowser() {
// Opera 8.0+
if ((!!window["opr"] && !!["opr"]["addons"]) || !!window["opera"] || navigator.userAgent.indexOf(' OPR/') >= 0) {
return 'opera';
}
// Firefox 1.0+
if (typeof window["InstallTrigger"] !== 'undefined') {
return 'firefox';
}
// Safari 3.0+ "[object HTMLElementConstructor]"
if (/constructor/i.test(window["HTMLElement"]) || (function(p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || (typeof window["safari"] !== 'undefined' && window["safari"].pushNotification))) {
return 'safari';
}
// Internet Explorer 6-11
if (/*@cc_on!@*/false || !!document["documentMode"]) {
return 'ie';
}
// Edge 20+
if (!(/*@cc_on!@*/false || !!document["documentMode"]) && !!window["StyleMedia"]) {
return 'edge';
}
// Chrome 1+
if (!!window["chrome"] && !!window["chrome"].webstore) {
return 'chrome';
}
// Blink engine detection
if (((!!window["chrome"] && !!window["chrome"].webstore) || ((!!window["opr"] && !!["opr"]["addons"]) || !!window["opera"] || navigator.userAgent.indexOf(' OPR/') >= 0)) && !!window["CSS"]) {
return 'blink';
}
}
谢谢大家。我在最近的浏览器上测试了这里的代码片段:Chrome 55,Firefox 50,IE 11和Edge 38,并且我得出了以下适用于所有浏览器的组合。我相信它可以改进,但对于需要快速解决方案的人来说,这是一个不错的选择:
var browser_name = '';
isIE = /*@cc_on!@*/false || !!document.documentMode;
isEdge = !isIE && !!window.StyleMedia;
if(navigator.userAgent.indexOf("Chrome") != -1 && !isEdge)
{
browser_name = 'chrome';
}
else if(navigator.userAgent.indexOf("Safari") != -1 && !isEdge)
{
browser_name = 'safari';
}
else if(navigator.userAgent.indexOf("Firefox") != -1 )
{
browser_name = 'firefox';
}
else if((navigator.userAgent.indexOf("MSIE") != -1 ) || (!!document.documentMode == true )) //IF IE > 10
{
browser_name = 'ie';
}
else if(isEdge)
{
browser_name = 'edge';
}
else
{
browser_name = 'other-browser';
}
$('html').addClass(browser_name);
它会向 HTML 添加一个 CSS 类,类名为浏览器的名称。
以下是 Rob 在 2016 年做出的答案,已经更新了包括 Microsoft Edge 和 Blink 检测的部分。
(编辑:我已经使用这些信息更新了Rob在上面的回答。)
// 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;
/* Results: */
console.log("isOpera", isOpera);
console.log("isFirefox", isFirefox);
console.log("isSafari", isSafari);
console.log("isIE", isIE);
console.log("isEdge", isEdge);
console.log("isChrome", isChrome);
console.log("isBlink", isBlink);
这种方法的美妙之处在于它依赖于浏览器引擎的属性,因此它甚至覆盖了派生浏览器,比如Yandex或Vivaldi,它们实际上与使用它们的引擎的主要浏览器兼容。唯一的例外是Opera,它依赖于用户代理嗅探,但是今天(即版本15及以上),甚至Opera本身也只是Blink的外壳。
MSAssertion
技巧已经调整到版本25了。但是因为很多开发者依赖于虚拟机,我会尝试将其调整到这个较旧的版本。明智之举。谢谢。 - pilauStyleMedia
(大写)对象特定于IE和Edge,并且似乎不会消失。 - pilautry
和 catch
来使用不同的浏览器错误消息。IE 和 Edge 混淆了,但我使用了 Rob W 的鸭子类型(基于这个项目:https://www.khanacademy.org/computer-programming/i-have-opera/2395080328)。var getBrowser = function() {
try {
var e;
var f = e.width;
} catch(e) {
var err = e.toString();
if(err.indexOf("not an object") !== -1) {
return "safari";
} else if(err.indexOf("Cannot read") !== -1) {
return "chrome";
} else if(err.indexOf("e is undefined") !== -1) {
return "firefox";
} else if(err.indexOf("Unable to get property 'width' of undefined or null reference") !== -1) {
if(!(false || !!document.documentMode) && !!window.StyleMedia) {
return "edge";
} else {
return "IE";
}
} else if(err.indexOf("cannot convert e into object") !== -1) {
return "opera";
} else {
return undefined;
}
}
};
return "firefox";
} else if(err.search("[object Error]") !== -1 && e.message != null && e.description != null){
return "IE";
} else if(err.search("cannot convert e into object") !== -1){
return "opera"; - Vadim