在JavaScript中检测IE版本(v9之前)

253

如果用户使用早于v9的Internet Explorer版本,我希望将其反弹到错误页面,因为我们不值得花时间和金钱来支持IE pre-v9。其他非IE浏览器的用户都可以正常使用且无需反弹。这是建议的代码:

if(navigator.appName.indexOf("Internet Explorer")!=-1){     //yeah, he's using IE
    var badBrowser=(
        navigator.appVersion.indexOf("MSIE 9")==-1 &&   //v9 is ok
        navigator.appVersion.indexOf("MSIE 1")==-1  //v10, 11, 12, etc. is fine too
    );

    if(badBrowser){
        // navigate to error page
    }
}

这段代码能实现吗?

在此之前,我想先回应几个可能会出现的评论:

  1. 是的,我知道用户可以伪造他们的 useragent 字符串,但我并不担心。
  2. 是的,我知道编程专家更喜欢检测特性支持而不是浏览器类型,但我认为这种方法在这种情况下并不合理。我已经知道所有(相关的)非 IE 浏览器都支持我需要的功能,而所有的 pre-v9 IE 浏览器都不支持。在整个站点逐个检查每个特性将是一种浪费。
  3. 是的,我知道有人试图使用 IE v1(或 >= 20)来访问网站将不会将 'badBrowser' 设置为 true 并且警告页面将无法正常显示。我们愿意承担这种风险。
  4. 是的,我知道 Microsoft 有 "条件注释" 可以用于精确的浏览器版本检测。但自从 IE 10 起,IE 就不再支持条件注释了,使这种方法变得绝对无用。

还有其他显而易见的问题需要注意吗?


125
“支持IE v9之前的版本不值得我们浪费时间和金钱。” 我很希望我能够做到。 - user377628
2
基于第二点,我不建议使用Modernizr(http://en.wikipedia.org/wiki/Modernizr)-每个人都必须在某个地方划定界限-但是IE9似乎是一个高标准。 - amelvin
1
条件注释只是普通的注释。只有IE将它们解释为特殊注释。IE10+不再这样做了。 - Andreas
3
IE 10将与非IE浏览器一样处理条件注释。它们是有效的HTML注释,将被视为这样的注释。我同意Andreas的看法,并认为条件注释是可行的方法。 - Tim Down
1
谁在乎IE10是否支持条件注释,如果它不是你要检测的浏览器之一?你不需要检测它是否是IE9或更高版本,你只需要检测它是否是IE8或更低版本。你的错误在于认为你需要弄清楚它是什么,才能知道它不是什么。这是不正确的。你不需要检测IE10,你只需要知道它不是IE8(或更低版本)。任何你放在lt IE 9条件中的代码都将在IE8及以下版本中运行,而其他地方则不会。就是这么简单。这是微软在IE方面做对的唯一一件事情。 - Jimbo Jonny
显示剩余5条评论
37个回答

13

这个方法适用于我。我将它用作重定向到一个页面,解释为什么我们不喜欢<IE9并提供我们推荐的浏览器链接。

<!--[if lt IE 9]>
<meta http-equiv="refresh" content="0;URL=http://google.com">
<![endif]-->

1
哦,那是一个很糟糕的问题。我使用一种更友好的方法,显示一个看起来像IE警告的div,当访问者点击它时,用户会跳转到http://browsehappy.com。 - Codebeat

10

您的代码可以执行检查,但正如您想的那样,如果有人尝试使用IE v1或>v19访问您的页面,将不会收到错误,因此更安全的方法是使用以下正则表达式进行检查:

var userAgent = navigator.userAgent.toLowerCase();
// Test if the browser is IE and check the version number is lower than 9
if (/msie/.test(userAgent) && 
    parseFloat((userAgent.match(/.*(?:rv|ie)[\/: ](.+?)([ \);]|$)/) || [])[1]) < 9) {
  // Navigate to error page
}

这不是一个好的答案。UA-sniffing是不可靠的。更多信息请参见:http://modernizr.com/docs/ - Jezen Thomas
3
@Jezen 有时候UA嗅探是可行的方式:https://github.com/Modernizr/Modernizr/issues/538 - István Ujj-Mészáros

8
根据微软参考页面的说明,从版本10开始,IE不再支持条件注释。

var ieDetector = function() {
  var browser = { // browser object

      verIE: null,
      docModeIE: null,
      verIEtrue: null,
      verIE_ua: null

    },
    tmp;

  tmp = document.documentMode;
  try {
    document.documentMode = "";
  } catch (e) {};

  browser.isIE = typeof document.documentMode == "number" || eval("/*@cc_on!@*/!1");
  try {
    document.documentMode = tmp;
  } catch (e) {};

  // We only let IE run this code.
  if (browser.isIE) {
    browser.verIE_ua =
      (/^(?:.*?[^a-zA-Z])??(?:MSIE|rv\s*\:)\s*(\d+\.?\d*)/i).test(navigator.userAgent || "") ?
      parseFloat(RegExp.$1, 10) : null;

    var e, verTrueFloat, x,
      obj = document.createElement("div"),

      CLASSID = [
        "{45EA75A0-A269-11D1-B5BF-0000F8051515}", // Internet Explorer Help
        "{3AF36230-A269-11D1-B5BF-0000F8051515}", // Offline Browsing Pack
        "{89820200-ECBD-11CF-8B85-00AA005B4383}"
      ];

    try {
      obj.style.behavior = "url(#default#clientcaps)"
    } catch (e) {};

    for (x = 0; x < CLASSID.length; x++) {
      try {
        browser.verIEtrue = obj.getComponentVersion(CLASSID[x], "componentid").replace(/,/g, ".");
      } catch (e) {};

      if (browser.verIEtrue) break;

    };
    verTrueFloat = parseFloat(browser.verIEtrue || "0", 10);
    browser.docModeIE = document.documentMode ||
      ((/back/i).test(document.compatMode || "") ? 5 : verTrueFloat) ||
      browser.verIE_ua;
    browser.verIE = verTrueFloat || browser.docModeIE;
  };

  return {
    isIE: browser.isIE,
    Version: browser.verIE
  };

}();

document.write('isIE: ' + ieDetector.isIE + "<br />");
document.write('IE Version Number: ' + ieDetector.Version);

然后使用:

if((ieDetector.isIE) && (ieDetector.Version <= 9))
{

}

1
这是整个网络上唯一有效的东西,至少是我尝试过的众多事物中最有效的...谢谢 ;) - Henrique C.
这段代码很好,但无法检测兼容性视图模式。我在使用IE 8的兼容性视图的IE 11上,但这段代码仍然显示“版本11”。编辑:这段代码太棒了!哈哈,它返回一个包含所有内容的对象。版本是11,但docModeIR等于9。谢谢! - MarceloBarbosa

6

针对IE 10和11:

您可以使用JavaScript并在HTML中添加一个类来维护条件注释的标准:

  var ua = navigator.userAgent,
      doc = document.documentElement;

  if ((ua.match(/MSIE 10.0/i))) {
    doc.className = doc.className + " ie10";

  } else if((ua.match(/rv:11.0/i))){
    doc.className = doc.className + " ie11";
  }

或者使用像bowser这样的库:

https://github.com/ded/bowser

或者使用modernizr进行特性检测:

http://modernizr.com/


2
我尝试了几个脚本和解决方案,但都没有起作用。然后我在项目中加入了Bowser,它就奏效了。因此,对于建议使用Bowser,我给出了一次好评。 - Moulde

4
这个问题已经被反复回答了,但这是你所需要的全部内容。
!!navigator.userAgent.match(/msie\s[5-8]/i)

此外,这里有一个沙盒,展示了正则表达式模式与最常见的IE用户代理字符串的匹配情况:https://regex101.com/r/lC6oP3/1 - Timothy Perez
@alessadro - 但这是预期的,不是吗?OP想要测试小于9... - nnnnnn

3

要检测Internet Explorer 10 | 11,您可以在body标签后立即使用此小脚本:

在我的情况下,我使用在head中加载的jQuery库。

<!DOCTYPE HTML>
<html>
<head>
    <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
</head>
<body>
    <script>if (navigator.appVersion.indexOf('Trident/') != -1) $("body").addClass("ie10");</script>
</body>
</html>

我喜欢这个,谢谢。我只需要检测10或11,因为我不支持之前的版本。 - Nearpoint
IE9也是Trident内核,但CSS支持与其他版本不同。您的检测认为至少是10,但这是不正确的。 - Codebeat

3
var Browser = new function () {
    var self = this;
    var nav = navigator.userAgent.toLowerCase();
    if (nav.indexOf('msie') != -1) {
        self.ie = {
            version: toFloat(nav.split('msie')[1])
        };
    };
};


if(Browser.ie && Browser.ie.version > 9)
{
    // do something
}

2
根据微软公司指南,以下是最佳解决方案,而且非常简单:

Microsoft

function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
    var rv = -1; // Return value assumes failure.
    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 )
    {
        if ( ver >= 8.0 ) 
            msg = "You're using a recent copy of Internet Explorer."
        else
            msg = "You should upgrade your copy of Internet Explorer.";
      }
    alert( msg );
}

确实,以防其他人尝试使用上述代码而来到这里,稍后的答案中的代码确实适用于IE11(https://dev59.com/D2gu5IYBdhLWcg3w8Lev#26375930)。但是要小心,它是否适用于IE12等版本?归根结底,最好将它们视为临时性的hack,随着新的浏览器版本发布,它们很可能会在以后失败(我甚至不会提及Edge)。 - Jeff Mergler

1
或者仅仅
//   IE 10: ua = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'; 
//   IE 11: ua = 'Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko'; 
// Edge 12: ua = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.71 Safari/537.36 Edge/12.0'; 
// Edge 13: ua = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Safari/537.36 Edge/13.10586'; 

var isIE = navigator.userAgent.match(/MSIE|Trident|Edge/)
var IEVersion = ((navigator.userAgent.match(/(?:MSIE |Trident.*rv:|Edge\/)(\d+(\.\d+)?)/)) || []) [1]

1

我为此编写了一个方便的下划线mixin。

_.isIE();        // Any version of IE?
_.isIE(9);       // IE 9?
_.isIE([7,8,9]); // IE 7, 8 or 9?

_.mixin({
  isIE: function(mixed) {
    if (_.isUndefined(mixed)) {
      mixed = [7, 8, 9, 10, 11];
    } else if (_.isNumber(mixed)) {
      mixed = [mixed];
    }
    for (var j = 0; j < mixed.length; j++) {
      var re;
      switch (mixed[j]) {
        case 11:
          re = /Trident.*rv\:11\./g;
          break;
        case 10:
          re = /MSIE\s10\./g;
          break;
        case 9:
          re = /MSIE\s9\./g;
          break;
        case 8:
          re = /MSIE\s8\./g;
          break;
        case 7:
          re = /MSIE\s7\./g;
          break;
      }

      if (!!window.navigator.userAgent.match(re)) {
        return true;
      }
    }

    return false;
  }
});

console.log(_.isIE());
console.log(_.isIE([7, 8, 9]));
console.log(_.isIE(11));
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>


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