服务器端检测Internet Explorer 11版本

21
我们都知道,IE11检测在服务器端语言中不起作用,因为Microsoft已经移除了IE/MSIE浏览器指示,现在完全是“Mozilla”。
我也知道浏览器检测/版本存在风险,但在过去,它已经服务于我们所有人。
网站的一些要求如下:
必须与某些Firefox版本及以上版本一起工作 必须与某些Chrome版本及以上版本一起工作 必须与某些Safari版本(一些旧版本和一些新版本)一起工作 必须支持IE >= 8
所以这里的问题是...... IE11在我的列表上显示不受支持。 我想从服务器(ASP.NET/MVC)的Web侧面支持它。
目前不清楚如何从服务器端检测到这个问题。 有人知道吗?
以下是IE 11中显示的用户代理:
"Mozilla/5.0(Windows NT 6.1; WOW64; Trident/7.0; rv:11.0)like Gecko"
rv:11.0告诉我们它是IE11,但对其进行解析仍意味着例如它可能是不被此类要求支持的特定版本的chrome或甚至firefox。
那么,最好的方法是如何确定它是否是IE 11或更高版本呢?
我不太确定是否应该从“Trident”及其后面搜索,因为我不知道其他浏览器是否使用它。
欢迎任何方向的指导。

4
在我看来,问题的存在是因为你在列白名单支持的浏览器而不是列黑名单不支持的浏览器。你自己提到了这可能会出现问题:你无法将未来的浏览器加入白名单,因为它们尚未存在。然而,你可以将不支持的浏览器列入黑名单,因为那些都是过去的事情。你考虑过这一点吗? - Jon
我同意你的看法,Jon。这需要一些测试,但让我看看我能做什么。 - Ahmed ilyas
@Jon - 重新审视代码和笔记,似乎有其他浏览器我们根本不支持 - 比如 Netscape 或移动设备或 Opera 或 Netscape...那么这该怎么处理呢?因为我没有这些浏览器来检查报告并拒绝它们。 - Ahmed ilyas
取决于您对不支持的浏览器有多严格的限制。如果您想要100%的严格控制,则黑名单将是一场噩梦,因为这些浏览器太多了。也许白名单可能是解决问题的方法——这取决于您的确切要求。 - Jon
@Jon - 我同意。我们有一组明确的“不允许”浏览器,而且并不多。任何Netscape,任何Safari(除了1个特定版本),以及任何Opera都是不被允许的。然后我们还有3种浏览器(IE、Firefox和Chrome)应该是特定版本或更高版本的才受支持。只是我不确定如何反转当前的代码(即使代码只有几行,它关键在于所支持的最低版本或更高版本,其他版本都不太受支持)。 - Ahmed ilyas
5个回答

17

使用正则表达式,如:

Regex.IsMatch(this.Request.UserAgent, @"Trident/7.*rv:11")

Trident是IE使用的渲染引擎的名称。正如您可以在维基百科文章中看到的那样,一些其他应用程序也使用Trident引擎。但是,在用户代理中搜索Trident不应该成为问题,因为没有其他主要浏览器使用Trident。

只有IE11使用Trident版本7,因此如果您使用正则表达式搜索Trident/7,它应该会找到IE11。


谢谢。我最终做了类似这样的事情并且它起作用了(使用正则表达式)。我选择不采用@pashapash建议的热修复方法,因为在生产环境中安装热修复需要经过漫长的流程。 - Ahmed ilyas
dotnet core已更改了UserAgent属性,现在可以使用Request.Headers["User-Agent"].ToString()获取它。 - BurnsBA

13
为了保持与现有代码的兼容性,我创建了一个自定义提供程序,因此Request.Browser将按预期返回信息。例如,Browser.Browser将为“IE”,而不是安装热修复程序后的新值“InternetExplorer”。
此外,这种方法返回IE的实际版本,而不是兼容视图中的版本7。请注意,如果需要检测,Browser.Type将在兼容视图中返回“IE7”,或者您可以轻松修改自定义提供程序以更改.Type。
这种方法很简单。从HttpCapabilitiesDefaultProvider派生出一个类,并将BrowserCapabilitiesProvider设置为一个类的实例。
在Global.asax.cs中:
protected void Application_Start(Object sender, EventArgs e)
{
    ...
    HttpCapabilitiesBase.BrowserCapabilitiesProvider = new CustomerHttpCapabilitiesProvider();
    ...
}

定义您的类:已更新以包括微软Edge浏览器

public class CustomerHttpCapabilitiesProvider : HttpCapabilitiesDefaultProvider
{
    public override HttpBrowserCapabilities GetBrowserCapabilities(HttpRequest request)
    {
        HttpBrowserCapabilities browser = base.GetBrowserCapabilities(request);

        // Correct for IE 11, which presents itself as Mozilla version 0.0
        string ua = request.UserAgent;

        // Ensure IE by checking for Trident
        // Reports the real IE version, not the compatibility view version. 
        if (!string.IsNullOrEmpty(ua))
        {
            if (ua.Contains(@"Trident"))
            {
                if (!browser.IsBrowser(@"IE"))
                {
                    browser.AddBrowser(@"ie");
                    browser.AddBrowser(@"ie6plus");
                    browser.AddBrowser(@"ie10plus");
                }

                IDictionary caps = browser.Capabilities;
                caps[@"Browser"] = @"IE";

                // Determine browser version
                bool ok = false;
                string majorVersion = null; // convertable to int
                string minorVersion = null; // convertable to double
                Match m = Regex.Match(ua, @"rv:(\d+)\.(\d+)");
                if (m.Success)
                {
                    ok = true;
                    majorVersion = m.Groups[1].Value;
                    minorVersion = m.Groups[2].Value; // typically 0
                }
                else
                {
                    m = Regex.Match(ua, @"Trident/(\d+)\.(\d+)");
                    if (m.Success)
                    {
                        int v;
                        ok = int.TryParse(m.Groups[1].Value, out v);
                        if (ok)
                        {
                            v += 4; // Trident/7 = IE 11, Trident/6 = IE 10, Trident/5 = IE 9, and Trident/4 = IE 8
                            majorVersion = v.ToString(@"d");
                            minorVersion = m.Groups[2].Value; // typically 0
                        }
                    }
                }

                if (ok)
                {
                    caps[@"MajorVersion"] = majorVersion;
                    caps[@"MinorVersion"] = minorVersion;
                    caps[@"Version"] = String.Format(@"{0}.{1}", majorVersion, minorVersion);
                }
            }
            else if (ua.Contains(@"Edge"))
            {
                if (!browser.IsBrowser(@"Edge"))
                {
                    browser.AddBrowser(@"edge");
                }

                IDictionary caps = browser.Capabilities;
                caps[@"Browser"] = @"Edge";

                // Determine browser version
                Match m = Regex.Match(ua, @"Edge/(\d+)\.(\d+)");
                if (m.Success)
                {
                    string majorVersion = m.Groups[1].Value;
                    string minorVersion = m.Groups[2].Value;
                    caps[@"MajorVersion"] = majorVersion;
                    caps[@"MinorVersion"] = minorVersion;
                    caps[@"Version"] = String.Format(@"{0}.{1}", majorVersion, minorVersion);
                }
            }
        }

        return browser;
    }
}

2
谢谢Doug - 这是一个保持与现有代码兼容性的好方法! - Mister Cook
1
更新适用于Microsoft Edge,感谢@MisterCook的提醒。 - Doug Domeny

8
我通过使用以下正则表达式解决了这个问题,首先检查使用什么浏览器访问网站,然后再进行匹配:
即使检查IE浏览器返回false,我也会继续使用这个正则表达式来检查用户代理是否匹配:
(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:)(\d+)
希望这对某些人有所帮助。我已经测试过,并且工作得很好。如果IE 12将RV更改为12,则我还将RV更改为12及以上,这也可以正常工作。

1
    public ActionResult Index()
    {
        var browser = this.Request.Browser;
        System.Diagnostics.Trace.WriteLine(browser.Browser); // InternetExplorer
        System.Diagnostics.Trace.WriteLine(browser.MajorVersion); // 11
        return View();
    }

请注意,您需要安装.NET 4.5或已安装http://support.microsoft.com/kb/2836939/en-us的.NET 4.0才能正确检测IE11。

正在运行.NET Framework 4.5。我也有.NET Framework 4.0,但该网站在.NET Framework 4.5浏览器中。浏览器报告“Mozilla”,MajorVersion为0。 - Ahmed ilyas
你需要在服务器端安装4.5或带有hotfix的4.0版本。mozilla/0 表示未安装 hotfix。请尝试安装它。如果该站点已经预编译,则还需要在用于预编译的机器上安装4.5/hotfix。 - PashaPash
谢谢。问题在于,在生产环境中安装热修补是一个漫长的过程,需要经过数周的测试才能获得通过。 - Ahmed ilyas
2
主要版本属性从我的服务器返回7,因此您不能依赖它。 - Chris Love

-1

听起来你正在对浏览器进行白名单处理,这不是一个好主意。通常情况下,你真的需要在客户端检测能力。MVC 真的不知道它是什么浏览器,Request.Browser 对象可以给你一些想法,但这并不可靠,特别是 IE 11。它告诉我在我的开发机上是版本 11,在我的服务器上是版本 7,这可能是一个灾难性的错误。

我构建单页应用程序,并采用了与 Google 类似的态度,只支持当前和前一个版本的浏览器。当我检测到过时的浏览器时,我会提供一个“核心”站点,只有一些基本的 CSS 和标记,没有 JavaScript。这样做更容易,使开发变得更加轻松。

无论如何,我检测的方式是测试当前版本的 IE,如下所示:

    public static bool IsModernIE() {

        return HttpContext.Current.Request.Browser.Browser == "InternetExplorer";

    }

这是一个HTML辅助方法。在您的cshtml中,您可以使用该测试。我在我的控制器中调用单个版本的测试。这是一种非常脆弱的方法。我基本上在现代IE(10/11)和旧版IE(9-)之间画了一条线。这个测试可能会在下一个版本中变得无关紧要,而且我还没有测试过Xbox One。

我有一个我使用的库,发布在GitHub上。我现在会称其为可用Alpha版,因此如果您喜欢,请试用它。我希望使测试更加可外部配置等。这是存储库的URL,https://github.com/docluv/SPAHelper。我实际上在我的博客http://love2dev.com上使用它。


有些人说我在使用白名单,有些人则说我在使用黑名单……那么应该用哪种?我们有一组要求,我正在遵循它们。 :) 要求是某些浏览器是可以的,而另一些则不太行,除非它们是特定版本。所以不幸的是,必须这样做。此外,您的IsModernIE()方法会在IE11及以上版本中失败。现在报告浏览器为Mozilla,而不是MSIE,IE或InternetExplorer。客户端检测对于需要完成的任务来说是不足够的... - Ahmed ilyas
1
没有系统热修补程序来修复浏览器文件,IE11会被检测为Mozilla。有了这个修补程序,IE11将被检测为“InternetExplorer”,与早期版本的IE(“IE”)不同。 - JT.
1
检测IE11+的唯一方法(没有补丁)是:(a)在App_Browsers中添加自己的.browser文件以便于IE11检测 - 不建议使用 - 或者(b)查找用户代理字符串中的Trident,如果浏览器被检测为Mozilla - JT.

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