【问题标题】:Internet explorer 11 detection on server side服务器端的 Internet Explorer 11 检测
【发布时间】:2013-11-15 11:24:52
【问题描述】:

我们都知道 IE11 检测不适用于服务器端语言,因为微软已经删除了 IE/MSIE 浏览器指示,现在完全是“Mozilla”。

我也知道进行浏览器检测/版本是有风险的,但过去对我们所有人都有好处。

网站的一些要求如下:

必须使用特定版本的 firefox 及更高版本 必须使用特定版本的 chrome 及更高版本 必须与某些版本的 safari 一起工作(一些在下面和一些更新) 必须使用 IE >= 8

这就是问题所在... IE11 在我的列表中表明它不受支持。我想从服务器上的 Web 端支持它(ASP.NET/MVC)

目前尚不清楚如何从服务器端检测到这一点。有人知道怎么做吗?

这是现在在 IE 11 中显示的用户代理:

“Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) 像壁虎”

rv:11.0 告诉我们它的 IE11,但是对其进行解析仍然意味着,例如,它可能是某个版本的 chrome,而这种要求甚至 Firefox 都不支持。

那么,在这里查看它是否确实是 IE 11 或更高版本的最佳方法是什么?

我不太确定从“三叉戟”开始搜索,因为我不知道其他浏览器是否使用它。

欢迎任何方向。

【问题讨论】:

  • 在我看来,问题的存在是因为您将支持的浏览器列入白名单,而不是将不受支持的浏览器列入黑名单。您提到自己可能会破坏:您不能将未来的浏览器列入白名单,因为它们还不存在。但是,您可以将不受支持的浏览器列入黑名单,因为这已经过去了。你考虑过这个吗?
  • 同意乔恩的观点。这需要一些测试,但让我看看我能做什么。
  • @Jon - 重新访问代码和注释,似乎还有其他浏览器是我们不支持的时期 - 比如一般的网景或移动设备或歌剧或网景......所以这怎么可能被处理,因为我没有这些浏览器来检查将报告的内容并拒绝它们?
  • 取决于您对禁止不受支持的浏览器的要求有多严格。如果您想要 100% 严格,那么黑名单将是一场噩梦,there are too many of them out there。也许白名单可能是一种方式 - 这取决于您的确切要求。
  • @Jon - 同意。我们有一套定义的“不去”,而且没有那么多。任何网景,任何野生动物园(除了1),任何歌剧都是不允许的。然后我们有 3 个浏览器(IE、firefox 和 chrome),它们应该是某个版本或更高的版本,它们是受支持的。只是不知道如何继续反转当前代码(即使代码只有几行,但它都是关于支持的最小版本或更高版本,其他一切都不是那么多)

标签: asp.net internet-explorer asp.net-mvc-4


【解决方案1】:

使用正则表达式,例如:

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

Trident 是 IE 使用的渲染引擎的名称。如您在 Wikipedia 文章中所见,其他一些应用程序也使用 Trident 引擎。但是在用户代理中搜索 Trident 应该没有问题,因为没有其他主流浏览器使用 Trident。

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

【讨论】:

  • 谢谢。我最终做了这样的事情并且工作(使用正则表达式)。我选择不采用@pashapash 建议的修补程序方法,因为在生产中安装修补程序必须经过一个漫长的过程。
  • dotnet core 更改了UserAgent 属性,现在使用Request.Headers["User-Agent"].ToString() 获取它
【解决方案2】:

为了保持与现有代码的兼容性,我创建了一个自定义提供程序,因此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();
    ...
}

定义你的类:更新包括微软边缘浏览器

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;
    }
}

【讨论】:

  • 感谢 Doug - 维护与现有代码兼容性的绝佳解决方案!
  • 为 Microsoft Edge 更新,感谢 @MisterCook 的呼唤。
【解决方案3】:

我在敲除系统后使用下面的正则表达式解决了这个问题,以检查正在使用什么浏览器访问该站点。

在这种情况下,即使浏览器“IE”被选中并返回 false,我也会继续使用这个正则表达式并检查它是否与用户代理匹配:

(?:\b(MS)?IE\s+|\bTrident\/7\.0;.*\s+rv:)(\d+)

我希望这对某人有所帮助。我对其进行了测试并且工作正常。我还将 rv 更改为 12 及更高版本,如果在 IE12 中将 rv 更改为 12,它也可以正常工作。

【讨论】:

    【解决方案4】:
        public ActionResult Index()
        {
            var browser = this.Request.Browser;
            System.Diagnostics.Trace.WriteLine(browser.Browser); // InternetExplorer
            System.Diagnostics.Trace.WriteLine(browser.MajorVersion); // 11
            return View();
        }
    

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

    【讨论】:

    • 运行 .NET Framework 4.5。我也有 .NET Framework 4.0,但该站点位于 .NET Framework 4.5 浏览器中。浏览器报告“Mozilla”并且 MajorVersion 为 0。
    • 您需要 4.5 或 4.0 以及服务器端的修补程序。 mozilla/0 表示未安装修补程序。尝试安装修补程序。如果网站是预编译的,那么你还需要在用于预编译的机器上安装 4.5/hotfix。
    • 谢谢。问题是,在生产环境中安装修补程序是一个漫长的过程,需要连续测试数周才能获得批准。
    • majorVersion 属性从我的服务器返回 7,所以你不能依赖它。
    【解决方案5】:

    听起来您将浏览器列入白名单,这不是一个好主意。通常,您确实需要对功能进行客户端检测。 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。客户端检测不足以完成需要完成的工作...
    • 如果没有系统修补程序来修补浏览器文件,IE11 会被检测为 Mozilla。修复后,IE11 被检测为“InternetExplorer”,与早期 IE 版本 (“IE”) 中列出的不同。
    • 在没有补丁的情况下检测 IE11+ 的唯一方法是 (a) 在 App_Browsers 中为 IE11 添加您自己的 .browser 文件 - 不推荐 - 或 (b) 在如果浏览器被检测为Mozilla,则为用户代理字符串。
    猜你喜欢
    • 1970-01-01
    • 2019-11-20
    • 1970-01-01
    • 2015-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多