.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服務即可.