简体   繁体   English

服务器端的Internet Explorer 11检测

[英]Internet explorer 11 detection on server side

We all know that IE11 detection does not work with server side languages because Microsoft has removed the IE/MSIE browser indication and now is fully "Mozilla". 我们都知道IE11检测不适用于服务器端语言,因为微软已经删除了IE / MSIE浏览器指示,现在完全是“Mozilla”。

I also know that doing browser detection/version is risky but has served us all well in the past. 我也知道做浏览器检测/版本存在风险,但过去一直很好。

some requirements for a website are things like: 网站的一些要求是这样的:

must work with certain version of firefox and above must work with certain version of chrome and above must work with certain version of safari's (some below and some newer) must work with IE >= 8 必须使用某些版本的firefox以上必须使用某些版本的chrome及以上必须使用某些版本的safari(一些下面和一些较新的)必须使用IE> = 8

so here is the problem... IE11 indicates on my list that it is not supported. 所以这就是问题... IE11在我的列表中指出它不受支持。 I want to support it from the web side of things on the server (ASP.NET/MVC) 我想从服务器上的东西的Web端支持它(ASP.NET / MVC)

it is not clear exactly how to detect this from the server side. 目前尚不清楚如何从服务器端检测到这一点。 Does anyone know how? 有谁知道怎么样?

this is the user agent now being shown in IE 11: 这是IE 11中显示的用户代理:

"Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko" “像Gecko一样的Mozilla / 5.0(Windows NT 6.1; WOW64; Trident / 7.0; rv:11.0)”

rv:11.0 tells us its IE11 however doing a parse on that will still mean that for example, it could be chrome of a certain version that is not supported in such a requirement or even firefox. rv:11.0告诉我们它的IE11,然而对它进行解析仍然意味着,例如,它可能是某个版本的chrome,在这样的要求中甚至不支持firefox。

so, what is the best way here to see if it is indeed IE 11 or higher? 那么,在这里看看IE 11或更高版本的最佳方式是什么?

I am not so sure about searching from "Trident" and onwards because I don't know if other browsers use that or not. 我不太确定从“Trident”开始搜索,因为我不知道其他浏览器是否使用它。

any direction is welcomed. 欢迎任何方向。

Use a Regular Expression like: 使用正则表达式,如:

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

Trident is the name of the rendering engine IE uses. Trident是IE使用的渲染引擎的名称。 Some other applications also use the Trident engine, as you can see in the Wikipedia article. 其他一些应用程序也使用Trident引擎,您可以在Wikipedia文章中看到。 But it shouldn't be a problem to search for Trident in the User Agent, since no other major browsers use Trident. 但是在用户代理中搜索Trident应该不是问题,因为没有其他主流浏览器使用Trident。

Only IE11 uses Trident version 7 so if you search for Trident/7 with the regex, it should find IE11. 只有IE11使用Trident版本7,所以如果你用正则表达式搜索Trident/7 ,它应该找到IE11。

To maintain compatibility with existing code, I created a custom provider so Request.Browser will return the information as expected. 为了保持与现有代码的兼容性,我创建了一个自定义提供程序,因此Request.Browser将按预期返回信息。 For example, Browser.Browser will be "IE" not "InternetExplorer", which is the new value after the hotfix is installed. 例如, Browser.Browser将是“IE”而不是“InternetExplorer”,这是安装此修补程序后的新值。

Additionally, this approach returns the actual version of IE, not version 7 when in compatibility view. 此外,此方法在兼容性视图中返回IE的实际版本,而不是版本7。 Note that Browser.Type will return "IE7" when in compatibility view in case you need to detect it, or you could easily modify the custom provider to change .Type as well. 请注意, Browser.Type在兼容性视图中将返回“IE7”,以防您需要检测它,或者您可以轻松修改自定义提供程序以更改.Type。

The approach is simple. 方法很简单。 Derive a class from HttpCapabilitiesDefaultProvider and set BrowserCapabilitiesProvider to an instance of your class. HttpCapabilitiesDefaultProvider派生一个类,并将BrowserCapabilitiesProvider设置为您的类的实例。

In Global.asax.cs: 在Global.asax.cs中:

protected void Application_Start(Object sender, EventArgs e)
{
    ...
    HttpCapabilitiesBase.BrowserCapabilitiesProvider = new CustomerHttpCapabilitiesProvider();
    ...
}

Define your class: UPDATED TO INCLUDE MICROSOFT EDGE BROWSER 定义您的课程: 更新为包括MICROSOFT EDGE BROWSER

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

I solved this by using the Regex below after having a knock out system to check what browser is being used to access the site. 我在使用淘汰系统后使用下面的Regex来检查这一点,以检查用于访问该站点的浏览器。

in this case, even if the browser "IE" is checked and returns false, I go ahead and use this regex and check to see if it is a match against the user agent: 在这种情况下,即使检查浏览器“IE”并返回false,我继续使用此正则表达式并检查它是否与用户代理匹配:

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

I hope this helps someone. 我希望这可以帮助别人。 I tested it and works fine. 我测试了它并且工作正常。 I also changed the rv to be 12 and upwards, and it works fine too in case if in IE12, they change rv to be 12. 我还将rv改为12及以上,如果在IE12中它们将rv改为12,它也可以正常工作。

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

Please note that you need .NET 4.5 or .NET 4.0 with http://support.microsoft.com/kb/2836939/en-us installed to correctly detect IE11. 请注意,您需要安装了http://support.microsoft.com/kb/2836939/en-us的 .NET 4.5或.NET 4.0才能正确检测IE11。

It does sound like you are whitelisting browsers, which is not a good idea. 听起来好像是白名单浏览器,这不是一个好主意。 You really need to do client-side detection of capabilities instead, generally. 通常,您确实需要对功能进行客户端检测。 MVC really does not know what browser it is, the Request.Browser object can give you some idea, but that is not really reliable, which is the case for IE 11. It tells me version 11 on my dev machine, but 7 on my server, which can be a catastrophic mistake. MVC真的不知道它是什么浏览器,Request.Browser对象可以给你一些想法,但这不是真的可靠,这是IE 11的情况。它告诉我我的开发机器上的版本11,但我的7服务器,这可能是一个灾难性的错误。

I build Single Page Applications and have adopted a similar attitude as Google about only supporting the current and previous version of a browser only. 我构建了单页应用程序,并采用了与Google类似的态度,仅支持当前和以前版本的浏览器。 When I detect an outdated browser I server a 'core' site that is just some basic CSS and markup, no JavaScript. 当我发现一个过时的浏览器时,我服务的是一个“核心”网站,它只是一些基本的CSS和标记,没有JavaScript。 It is just easier that way, makes development so much easier. 这种方式更简单,使开发变得更加容易。

Anyway the way I detect is to test for the current versions of IE like so: 无论如何,我检测的方式是测试当前版本的IE,如下所示:

    public static bool IsModernIE() {

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

    }

It is an HTML helper method. 它是一个HTML帮助方法。 So in your cshtml you can use the test. 所以在你的cshtml中你可以使用测试。 In my controller I call the individual version tests. 在我的控制器中,我调用了各个版本的测试。 This is ultimately a very fragile way to do it. 这最终是一种非常脆弱的方式。 I am basically drawing a line in the sand between modern IE (10/11) and old IE (9-). 我基本上在现代IE(10/11)和旧IE(9-)之间画了一条线。 This test could be irrelevant with the next version and I have not tested against say Xbox One yet. 这个测试可能与下一个版本无关,我还没有测试过Xbox One。

I have a library I use, posted on GitHub. 我有一个我使用的库,发布在GitHub上。 I would call it usable Alpha right now, so take it for that and run with it if you like. 我现在称它为可用的Alpha,所以如果你愿意的话就把它当作它来运行吧。 I want to make the tests more externally configurable, etc. here is the URL for the repository, https://github.com/docluv/SPAHelper . 我想让测试更加外部可配置,等等。这里是存储库的URL, https://github.com/docluv/SPAHelper I actually use it on my Blog, http://love2dev.com . 我实际上在我的博客http://love2dev.com上使用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM