如何检测IE11?

217

当我想检测IE时,我使用这段代码:

function getInternetExplorerVersion()
{
  var rv = -1;
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re  = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  return rv;
}
function checkVersion()
{
  var msg = "You're not using Internet Explorer.";
  var ver = getInternetExplorerVersion();

  if ( ver > -1 )
  {
    msg = "You are using IE " + ver;
  }
  alert( msg );
}

但是IE11返回的是"您未使用Internet Explorer"。 我该如何检测?


2
请参考以下链接:https://dev59.com/b2Qm5IYBdhLWcg3wowWw - dave1010
1
基于用户代理的任何东西都是有缺陷的。它太容易被欺骗了。现在,也许这不是一个问题,但在我看来,浏览器检测脚本应该有公平的机会来检测伪装。我使用一种组合方式,包括条件注释、尝试强制转换document.documentMode,然后查看下面的window.MSInputMethodContext,就像Paul Sweatte所说的那样。我想发布我的代码,但这只是徒劳无功。 - David G
3
IE11的用户代理为: Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko操作系统类型:6.1 - win7,6.3 - win81 - razor
1
请看我在这里的回答:https://dev59.com/XWEh5IYBdhLWcg3w9nhj - Royi Namir
1
这是我找到的最佳解决方案: https://dev59.com/_mMk5IYBdhLWcg3w5R2k#20201867if (Object.hasOwnProperty.call(window, "ActiveXObject") && !window.ActiveXObject) { // 是IE11 } - xorcus
显示剩余2条评论
16个回答

225
IE11不再以“MSIE”报告,根据this list of changes的说法,这是有意为之,以避免误检测。
如果您确实想知道它是否为IE,则可以在用户代理中检测“Trident/”字符串,如果navigator.appName返回Netscape,可以尝试以下方法(未经测试):

function getInternetExplorerVersion()
{
  var rv = -1;
  if (navigator.appName == 'Microsoft Internet Explorer')
  {
    var ua = navigator.userAgent;
    var re = new RegExp("MSIE ([0-9]{1,}[\\.0-9]{0,})");
    if (re.exec(ua) != null)
      rv = parseFloat( RegExp.$1 );
  }
  else 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 );
  }
  return rv;
}

console.log('IE version:', getInternetExplorerVersion());

请注意,IE11(据我所知)仍处于预览阶段,用户代理可能会在发布之前发生变化。

84
很遗憾,现在IE11发布了,我们的代码只在IE11中出现问题,而正确检测IE则可以解决这个问题...“避免误检”是有意为之。 - Izkata
69
如果版本不重要,我把这个解决方案转换成了一个布尔函数。函数名为 isIE() ,如果浏览器是微软的 Internet Explorer 或者是使用 Trident 引擎的 Netscape 浏览器(且版本号大于等于 0),则返回 true,否则返回 false。具体实现代码如下:function isIE() { return ((navigator.appName == 'Microsoft Internet Explorer') || ((navigator.appName == 'Netscape') && (new RegExp("Trident/.*rv:([0-9]{1,}[\.0-9]{0,})").exec(navigator.userAgent) != null))); } - rg89
6
根据这里的HTML5规范,IE实际上是在遵循标准。因此,是有意为之的,但这是根据新标准(废弃旧的HTML API)的要求。 - Mark Avenius
12
他们这样做的原因是故意的。他们想要像这样破解浏览器检测脚本。实际上应该是:他们希望像这样让数十亿个网站出现问题。 - Avatar
16
这个对我有用:var isIE11 = !!navigator.userAgent.match(/Trident\/7\./); 来源 - Avatar
显示剩余10条评论

89

使用!(window.ActiveXObject) && "ActiveXObject" in window来显式检测IE11。

要检测任何IE(除了Edge之前的版本,“Trident”),请改用"ActiveXObject" in window


2
这篇微软文章建议这个解决方案可能已经不再适用了 http://msdn.microsoft.com/en-us/library/ie/dn423948(v=vs.85).aspx - Alan
5
这篇文章实际上阐述了我的方法为什么有效。根据文章所述,在IE11中(以及非微软浏览器中),尝试访问window.ActiveXObject会返回undefined。使用JavaScript的in运算符进行测试在所有Microsoft浏览器中返回true,因此这两种情况严格适用于IE11。如果Microsoft更改了in运算符的行为,那么是的,这种方法将无法使用。 - mcw
5
在Edge浏览器中,window对象中的"ActiveXObject"返回False。 - Neo
10
@Neo Edge 不是IE,OP的问题是如何检测IE11。 - mastazi
1
@ mastazi 是的,但在这个答案中提到了 ActiveXObject 可以用来检测任何 IE 版本。虽然 Edge 是否应该被称为 IE 的一个版本还有争议(微软肯定不想这么说),但对于许多开发人员来说,IE 已经成为任何默认 Microsoft 浏览器的代名词。 - Neo
显示剩余6条评论

47

3
这对我来说似乎更加健壮。基于用户代理的任何东西肯定是相当无用的。 - David G
1
非常感谢,已经可以工作了,不需要使用ActiveXObject。 - Tarık Özgün Güner
1
@tdakhla 已更新以过滤 IE Edge。 - Paul Sweatte
重要提示:如果这些答案中有任何一个似乎无法正常工作,请检查模拟设置。我本来会将此答案标记为不正确的,但后来我检查了模拟,并发现一些内部网络兼容性设置正在覆盖显示模式,一旦将其排除在外,这个解决方案就对我起作用了。 - Shaun
2
刚刚确认在非IE、IE8、9、10、Edge 14、15中为#false。只有在IE11中为#true。没有测试文档模式激活的情况。使用Browserstack进行了测试。 - danjah
这对我有用。有一个基本的帮助程序 const isIE11 = () => !!window.MSInputMethodContext && !!document.documentMode; - jackhowa

15

我已经阅读了你的答案并进行了混合。它似乎可以在Windows XP(IE7 / IE8)和Windows 7(IE9 / IE10 / IE11)上运行。

function ie_ver(){  
    var iev=0;
    var ieold = (/MSIE (\d+\.\d+);/.test(navigator.userAgent));
    var trident = !!navigator.userAgent.match(/Trident\/7.0/);
    var rv=navigator.userAgent.indexOf("rv:11.0");

    if (ieold) iev=new Number(RegExp.$1);
    if (navigator.appVersion.indexOf("MSIE 10") != -1) iev=10;
    if (trident&&rv!=-1) iev=11;

    return iev;         
}
当然,如果我返回0,则表示没有IE。

13

从User-Agent获取IE版本

var ie = 0;
try { ie = navigator.userAgent.match( /(MSIE |Trident.*rv[ :])([0-9]+)/ )[ 2 ]; }
catch(e){}

工作原理: 所有 IE 版本的用户代理字符串包括一个部分“MSIE 空格版本号”或“Trident其他文本rv空格或冒号版本号”。 我们可以通过 String.match() 正则表达式获取版本号,使用 try-catch 块缩短代码,否则我们需要为非 IE 浏览器测试数组边界。

注意: 用户代理可以被欺骗或省略,有时如果用户将浏览器设置为“兼容模式”,则可能无意中实现。但实际上这似乎并不是什么问题。


获取 IE 版本而不使用用户代理

var d = document, w = window;
var ie = ( !!w.MSInputMethodContext ? 11 : !d.all ? 99 : w.atob ? 10 : 
d.addEventListener ? 9 : d.querySelector ? 8 : w.XMLHttpRequest ? 7 : 
d.compatMode ? 6 : w.attachEvent ? 5 : 1 );
工作原理:每个版本的IE都会添加前一版本中没有的附加功能支持。因此,我们可以自上而下地测试这些功能。这里使用了三目运算符以简洁为主,但if-thenswitch语句同样适用。变量ie被设置为整数5-11,或1表示更早的版本,或99表示更新的非IE浏览器。如果您只想测试IE 1-11,则可以将其设置为0。

注意:对象检测可能会出现问题,如果您的代码在添加了针对像document.addEventListener之类的polyfill的第三方脚本的页面上运行。在这种情况下,用户代理是最佳选择。


检测浏览器是否现代化

如果您仅关心浏览器是否支持大多数HTML 5和CSS 3标准,您可以合理地假设IE 8及以下版本仍然是主要问题应用程序。测试window.getComputedStyle将为您提供相当不错的现代浏览器组合(IE 9,FF 4,Chrome 11,Safari 5,Opera 11.5)。IE 9极大地改进了对标准的支持,但本地CSS动画需要IE 10。

var isModernBrowser = ( !document.all || ( document.all && document.addEventListener ) ); 

“从用户代理中获取IE版本”的功能很好!只是为了确保,这将显示所有版本,包括IE11吗? - omer
1
@omer 是的,因为它寻找字符串"MSIE"或"Trident";后者是由IE 11及以上版本使用的。因此,它将适用于所有未来的IE版本,直到微软更改其浏览器引擎的名称。我相信新的Edge浏览器仍然使用Trident。 - Beejor
这个很好用,谢谢@Beejor!我使用了你的答案实现了一个简单的重定向到另一个页面:`var ie = 0; try { ie = navigator.userAgent.match( /(MSIE |Trident.*rv[ :])([0-9]+)/ )[ 2 ]; } catch(e){} if (ie !== 0) { location.href = "../ie-redirect/redirect.html"; } ` - BernardV
@BernardV 看起来不错!一个快速的提示:如果您可以访问服务器,在那里检测用户代理可能效果更好,因为用户不会注意到任何重定向/闪烁、较少的HTTP请求等。但是在紧急情况下,也可以使用JS实现。 - Beejor

10

AngularJS 是用这种方式实现的。

msie = parseInt((/msie (\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
if (isNaN(msie)) {
  msie = parseInt((/trident\/.*; rv:(\d+)/.exec(navigator.userAgent.toLowerCase()) || [])[1]);
}

如果是IE浏览器,msie将会是正数,而对于其他浏览器如Chrome、Firefox等,则为NaN。

为什么?

从Internet Explorer 11开始,用户代理字符串发生了重大变化。

请参考:

msdn #1 msdn #2


7

解决方案:

function GetIEVersion() {
  var sAgent = window.navigator.userAgent;
  var Idx = sAgent.indexOf("MSIE");
  // If IE, return version number.
  if (Idx > 0)
    return parseInt(sAgent.substring(Idx+ 5, sAgent.indexOf(".", Idx)));

  // If IE 11 then look for Updated user agent string.
  else if (!!navigator.userAgent.match(/Trident\/7\./))
    return 11;

  else
    return 0; //It is not IE

}
if ((GetIEVersion() > 0) || (navigator.userAgent.toLowerCase().indexOf('firefox') > -1)){
  alert("This is IE " + GetIEVersion());
}else {
  alert("This no is IE ");
}  


1
我的最爱 - 适用于IE6-10和IE11。我还添加了一个检查边缘的功能。 - AlbatrossCafe
这会将Firefox检测为这是IE 0 - KSPR

3
我将使用更简单的方法:
navigator全局对象有一个名为touchpoints的属性,在Internet Explorer 11中称为msMaxTouchPoints。
因此,如果您寻找:
navigator.msMaxTouchPoints !== void 0 

您可以找到Internet Explorer 11。

1
它还返回在IE 10(Win 7)上打开。 - Chemical Programmer

2

试一试:

var trident = !!navigator.userAgent.match(/Trident\/7.0/);
var net = !!navigator.userAgent.match(/.NET4.0E/);
var IE11 = trident && net
var IEold = ( navigator.userAgent.match(/MSIE/i) ? true : false );
if(IE11 || IEold){
alert("IE")
}else{
alert("Other")
}

错误代码,因为Acoo浏览器在用户代理中使用了“MSIE”。请访问http://www.useragentstring.com/pages/Acoo%20Browser/。 - User
错误的参数。 我已经在所有IE浏览器上进行了测试,甚至在Win8设备上也进行了测试。 - Krunal
你测试了IE11浏览器,但没有测试Acoo浏览器。而Acoo浏览器在用户代理中使用“MSIE”,就像我之前说的那样,所以IEold也将Acoo浏览器检测为IEold(即IE的旧版本)。我确信Acoo浏览器在用户代理中使用“MSIE”,因为我已经在一个JavaScript测试网站上使用Acoo浏览器进行了navigator.userAgent测试(测试网站:http://w3schools.com)。 - User
你能否给出更好的解决方案? - Krunal
你可以使用!navigator.userAgent.match("Acoo Browser;") && navigator.userAgent.match(/MSIE/i) ? true : false,但这并不总是有效的,因为Acoo浏览器并不总是在其用户代理中包含"Acoo Browser;",但实际上你不需要关心Acoo浏览器是否在其用户代理中包含"MSIE",因为Acoo浏览器几乎与MSIE相同。 - User

2
var ua = navigator.userAgent.toString().toLowerCase();
var match = /(trident)(?:.*rv:([\w.]+))?/.exec(ua) ||/(msie) ([\w.]+)/.exec(ua)||['',null,-1];
var rv = match[2];
return rv;

如果您正在使用正则表达式进行检查,可以添加i标志以使其不区分大小写,而无需使用.toLowerCase()方法。也不需要.toString()方法。 - Jake Rowsell

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