Please read my blog's comment policy here.
If you found this post, chances are good that you’re searching for IE11’s User-Agent string.
Were you planning to control your website’s behavior based on the browser “sniffed” from the User-Agent (UA) string?
Please don’t; use feature detection instead (Ref1, Ref2).
Poorly implemented (non-futureproof) User-Agent sniffing has proven to be the top compatibility problem encountered each time a new version of Internet Explorer ships. As a consequence, the logic around the user-agent string has grown increasingly complicated over the years; the introduction of Compatibility Modes has meant that the browser now has more than one UA string, and legacy extensibility of the string was deprecated after years of abuse.
By way of example, consider...
Without the hotfix's updated browser definition file, your pages might omit the script blocks from all pages sent to an IE11 client.
See why UA-sniffing is evil?
By default, Internet Explorer 11 on Windows 8.1 sends the following User-Agent string:
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko
This string is deliberately designed to cause most UA-string sniffing logic to interpret it either Gecko or WebKit. This design choice was a careful one—the IE team tested many UA string variants to find out which would cause the majority of sites to “just work” for IE11 users.
Contrast this string with the old IE10 on Windows 8 UA string:
Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)
Many websites would scan for the MSIE token and, if present, return non-standard markup which would not render properly in modern versions of IE.
Internet Explorer 11 continues the IE9 tradition of exposing extensible tokens in the navigator.userAgent property but not sending those tokens in the request header. For instance, by default this property returns the following on IE11/Win8.1:
Mozilla/5.0 (Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C; rv:11.0) like Gecko
If the user chooses to render a site in Compatibility View (click Tools > Compatibility View Settings) then IE will send a User-Agent string that mimics Internet Explorer 7’s UA string:
Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.3; Trident/7.0; .NET4.0E; .NET4.0C)
By default, sites in the Intranet Zone render in Compatibility view, so this is the User-Agent string they’ll see.
Internet Explorer 10 introduced the ability for the downloaded Compatibility View List to specify arbitrary UA strings on a per-site basis, to handle cases where a given website only works with a particular UA string.
If you use Fiddler to examine the XML of IE11’s Compatibility View List (e.g. https://iecvlist.microsoft.com/IE11/1375395130872/iecompatviewlist.xml) you will see that it contains a number of UA strings:
…each of which can be sent to a particular domain to help ensure that it renders properly in IE10+:
Obviously, maintaining Compatibility View Lists requires a significant investment on the part of the IE team—resources which could be used to implement more new standards, performance improvements, etc. Please please please: use feature detection rather than User-Agent sniffing.
PS: Also note that in IE11 mode, the navigator.appName property returns Netscape; older versions returned Microsoft Internet Explorer. The new value matches all major browsers including Safari, Chrome, and Firefox.
Did you consider replacing the Mozilla token? This was useful in the IE3 days, but are there really any websites still sniffing for it that actually work in IE11?
[EricLaw] Yes, many websites depend on this token today. You can use the F12 Developer Tools or Fiddler to set the UA string to anything you like and watch what breaks. Of course, keep in mind that the IE Compatibility team tests hundreds of thousands of sites (or more), so they have a better picture of what breaks than most.
Is there a way to use feature detection for bug connect.microsoft.com/.../781964?
How can one get a browser's file upload size limit without User-Agent sniffing?
[EricLaw] Typically, a site should probably be using XmlHttpRequest to upload chunks of a file loaded using the File API, which eliminates any sort of "limit." For downlevel browsers, it's not clear what exactly you'd do differently based on the limit (which isn't the part of any browser's formal contract and thus is subject to change in updates).
You recommend to use "Feature Detection" rather than browser detection. However, how are we supposed to work-around IE specific bugs, if we can't detect it due to the browser "deliberately lying"?
For example this one? We had a fix on the server in place that was ensuring the caching headers were not present for clients sending in User-Agent containing "MSIE", but we can't do this anymore!
Issue we were trying to work-around:
I think this is a legitimate case of user agent detection, so just detect "Trident" or "MSIE". "Trident" exists since Internet Explorer 8 or 9, I believe.
How can I permanently change IE user agent string? I need IE11 to always use the IE9 user agent string
If the X-UA-Compatible has been set to IE=9, IE11 should send the IE9 user agent string *not* the IE11 user agent string!.
[EricLaw] It's not clear how you imagine that would work. IE sends the User-Agent in the Request header. It's not until the Response to that request is received that it gets the Server's X-UA-Compatible directive.
I just discovered the issue Kevin Sours mentions but I realized that while I observed the same symptoms, i.e. IE prompting for a JSON response to be downloaded, I'm not sure that my instance has the same cause as others.
What seems to be the cause of the behavior, relative to other browsers that don't exhibit it, is that IE is sending "text/html, application/xhtml+xml, */*" in the request Accept header and Chrome is sending "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8".
In my case, I have an endpoint in my application that should return results in either HTML or JSON and I had hoped to do so based on the requested content type. The Accept header examples above are for the case that I expect to return HTML. Because Chrome supplied a quality score for the 'any' type, the portion of my app that handles content negotiation (a library actually) determines that HTML is the best response type. But because IE does not include a quality score there is no actual 'best' type, tho I would expect either the order of the requested and offered types or the fact that JSON is an 'any' match to cause HTML to be the chosen response type.