.net framework4.5.1之前的版本有一个非常愚蠢的设定, 它为每个浏览器设置了一个浏览器定义文件, 通过正则表达式来匹配浏览器的userAgent, 然后来定义一些功能集.
这种做法有一个显而易见的问题, 浏览器是会经常升级的, 每次升级后, userAgent都会有变化, 这就导致.net framework的正则表达式跟新版本的浏览器匹配失败, 于是新版本浏览器被认定为"无法识别的浏览器", 对这种"无法识别的浏览器", .net framework的决定是: 大部分的功能不予支持, 其中javascript就是不被支持的功能之一.
可笑的是,被这个愚蠢的设定伤害最深的却正是微软自己.
当.net 4.0发布时, IE浏览器的最高版本是9.0, 于是.net 4.0的浏览器定义文件只能识别IE6-9, 后来IE10发布了, 问题就来了, 当用IE10访问.net 4.0的网站时, 最经常看到的错误提示就是"__doPostBack is not defined", 之所以会报__doPostBack未定义, 是因为这个函数本来应该由.net framework自动生成, 但是由于IE10被标记为不支持javascript, 所以服务器端发回的文件中就不包括任何的js代码, 于是页面上的函数尝试调用__doPostBack时, 就会报错.
所以实际上,这个错误只是个表象,真正的原因是脚本被服务器端禁用了.
为了解决这个问题,微软发布了一个hotfix: http://support.microsoft.com/kb/2600088
当在服务器上安装了这个hotfix时, 就会在.net 4.0的浏览器定义文件中增加对ie10的支持.
可是,故事并没有到这里结束. 随后.net 4.5发布, .net 4.5已经内置了对ie10的支持. 但是不久, 更高版本的IE11又发布了.
让人不可理解的是, .net4.0 不支持IE10这件事, 微软应该已经从中吸取教训了, 但是结果却是没有.
上述补丁仅仅能让服务器识别IE10, 却仍然不能识别IE11, .net 4.5和.net 4.0出了一样的状况, 不能识别最新版的IE: 当用IE11访问.net 4.5的网站时, 同样将遇到脚本被禁用的问题.
这次微软大约是有点不好意思再发补丁了, 于是直到我写这篇文章时为止,仍然没有修补补丁, 官方的处理方式只有一种, 安装.net 4.5.1, 可是如果服务器是.net 4.0的, 并且因为兼容问题, 暂时无法升级到.net 4.5的, 就完全没有官方的处理办法了.
.net 4.5.1终于从前两次的事故中吸取了一点教训, 它并没有定义一个新的用于识别IE11的正则表达式, 而是增强了通用浏览器的功能支持, 于是这条规则可以这样描述: 凡是被识别为"Mozilla"的浏览器, 增强其功能, 使它支持javascript, 以及其它几项以前不支持的功能. 而IE11的userAgent就是以Mozilla打头的, 所以将作为Mozilla通用浏览器进行处理.
顺带着说一句: 现在的浏览器基本上都是以Mozilla打头的, 如firefox, chrome, ie10以上版本, 其userAgent都是Mozilla/5.0 开头. 所以几乎可以说, Mozilla浏览器就意味着"现代通用浏览器". 更有意思的是, IE11 的appName竟然改成了Netscape, 而不再是Microsoft Internet Explorer, 从种程度上来说, IE10即是最后一版"IE".
那么对于不想或不能安装.net 4.5.1的服务器如何处理? 没办法, 只能手工处理.
实际上这个浏览器定义文件也很简单, 它位于c:\Windows\Microsoft.Net\Framework\v4.xxx\Config\Browsers\ 文件夹下, (对于64位的服务器,会有Framework和Framework(64)两个文件夹, 我看了一下,这两个文件夹下的浏览器定义文件是一样的, 究竟是哪个在起作用, 我也不清楚, 保险起见, 修改的时候最好两个地方都改) 在这个文件夹下会看到10个左右扩展名为.browser的文件, 其中ie.browser即是用来识别ie6-10 的, default.browser是默认的"不能识别的浏览器", generic.browser中保存着对Mozilla浏览器的处理方式. 因此, 需要修改的就是这个文件.
用任意文本编辑器打开generic.browser, (保险起见, 最好先备份一下原文件)修改其内容如下:
<browsers> <browser id="GenericDownlevel" parentID="Default"> <identification> <userAgent match="^Generic Downlevel$" /> </identification> <capture> </capture> <capabilities> <capability name="cookies" value="false" /> <capability name="ecmascriptversion" value="1.0" /> <capability name="tables" value="true" /> <capability name="type" value="Downlevel" /> </capabilities> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.Menu" adapterType="System.Web.UI.WebControls.Adapters.MenuAdapter" /> </controlAdapters> </browser> <browser id="Mozilla" parentID="Default"> <identification> <userAgent match="Mozilla" /> </identification> <capture> </capture> <capabilities> <capability name="browser" value="Mozilla" /> <capability name="cookies" value="true" /> <capability name="ecmascriptversion" value="3.0" /> <capability name="frames" value="true" /> <capability name="inputType" value="keyboard" /> <capability name="isColor" value="true" /> <capability name="isMobileDevice" value="false" /> <capability name="javascript" value="true" /> <capability name="javascriptversion" value="1.5" /> <capability name="maximumRenderedPageSize" value="300000" /> <capability name="screenBitDepth" value="8" /> <capability name="supportsBold" value="true" /> <capability name="supportsCallback" value="true" /> <capability name="supportsCss" value="true" /> <capability name="supportsDivNoWrap" value="true" /> <capability name="supportsFileUpload" value="true" /> <capability name="supportsFontName" value="true" /> <capability name="supportsFontSize" value="true" /> <capability name="supportsImageSubmit" value="true" /> <capability name="supportsItalic" value="true" /> <capability name="supportsMaintainScrollPositionOnPostback" value="true" /> <capability name="supportsMultilineTextBoxDisplay" value="true" /> <capability name="supportsXmlHttp" value="true" /> <capability name="tables" value="true" /> <capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" /> <capability name="type" value="Mozilla" /> <capability name="w3cdomversion" value="1.0" /> </capabilities> </browser> <!-- See WebKitDetect.js --> <browser id="WebKit" parentID="Mozilla"> <identification> <userAgent match="AppleWebKit" /> </identification> <capture> <userAgent match="AppleWebKit/(?'layoutVersion'\d+)" /> </capture> <capabilities> <capability name="layoutEngine" value="WebKit" /> <capability name="layoutEngineVersion" value="${layoutVersion}" /> </capabilities> </browser> <gateway id="WebKitMobile" parentID="WebKit"> <identification> <userAgent match="Mobile( Safari)?/(?'iOSVersion'[^ ]+)" /> </identification> <capture> <userAgent match="Mozilla/5.0 \((?'deviceName'[^;]+)" /> </capture> <capabilities> <capability name="mobileDeviceModel" value="${deviceName}" /> <capability name="isMobileDevice" value="true" /> <capability name="ecmascriptversion" value="3.0" /> <capability name="javascript" value="true" /> <capability name="javascriptversion" value="1.6" /> <capability name="w3cdomversion" value="1.0" /> <capability name="supportsAccesskeyAttribute" value="true" /> <capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" /> <capability name="cookies" value="true" /> <capability name="frames" value="true" /> <capability name="supportsCallback" value="true" /> <capability name="supportsDivNoWrap" value="false" /> <capability name="supportsFileUpload" value="true" /> <capability name="supportsMaintainScrollPositionOnPostback" value="true" /> <capability name="supportsMultilineTextBoxDisplay" value="true" /> <capability name="supportsXmlHttp" value="true" /> <capability name="tables" value="true" /> </capabilities> </gateway> </browsers>
保存后, 回退到v4.xxx 文件夹下, 执行aspnet_regbrowsers -i, 然后执行iisreset 重启IIS服务即可.