你是否遇到過當使用一個涉及到Cookie操做的網站或者管理系統時,IE 六、七、八、9下都跑的好好的,惟獨到了IE十、11這些高版本瀏覽器就不行了?好吧,這個問題碼農連續2天內遇到了2次。那麼,咱們就來看看,這個問題的來龍去脈。javascript
先說下這2次的使用場景,一次是在某頁面中,先存Cookie,而後再入庫記錄相關數據,可是發佈到生產環境後,入庫操做沒有發生;後來經過打印日誌發現問題卡在這裏:java
if (Request.Browser.Cookies)
也就是說,在客戶端是IE10的環境下,這裏返回False!納尼,IE10默認配置下不支持Cookie?微軟你玩個人吧。正則表達式
第二次是某地市的升級測試,在IE10的環境下,自服務網站登陸失敗;這個問題很奇怪,由於以前已經升級過多個地市了,IE10使用都正常。這極大的引發了碼農的興趣,由此引出了此文。瀏覽器
描述完場景,咱們就來分析分析。雖然直覺告訴碼農,多是Cookie的讀取或寫入有問題,但畢竟直覺這玩意兒不靠譜,咱仍是得用事實和證聽說話。國際慣例,先抓個HTTP包瞧瞧:服務器
上圖是IE10下登陸失敗時,服務端返回的HTTP響應頭;下圖是其它瀏覽器正常登陸時,服務端返回的HTTP響應頭,注意紅色框框標註部分;cookie
致使問題的直接緣由,很清晰了吧:服務器響應請求時,沒有回發 Set-Cookie 頭,沒有這個頭,客戶端瀏覽器就沒法寫入Cookie。因此基於Form認證(在Cookie中會存入加密票據)的自服務網站,會沒法登陸。app
這時,你可能會以爲奇怪了,爲啥只有IE十、IE11 會這樣,其它IE瀏覽器跑的妥妥的呢?嗯,爲了知足你的好奇心,咱們繼續分析。dom
若是你的機器上裝了.NET的FrameWork,打開這個目錄 C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\Browsers。科普下,文件夾裏面的.browser文件是全局訪問的,用於標識發出請求的瀏覽器,並標識這些瀏覽器具有的功能。若是要作定製修改(好比針對特定移動設備),只需把相應的.browser文件複製到應用程序的\App_Browsers文件夾中修改便可。先用記事本打開 ie.browser 這個文件,ecmascript
注意圖中標註爲紅色部分的正則表達式;而後再來看看,微軟公佈的IE10的User-Agent : Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0),MSIE版本號由之前的1位數字(5-9)變成了如今的2位數字(10),很明顯,沒法匹配上面的正則了吧。因此,因爲沒法正確識別IE10的User-Agent,因此ASP.NET把它看作是未知的瀏覽器,認爲它不支持Cookie,由此而產生了一系列與Cookie相關的問題。ide
問題的根本總算是知道了,那麼該如何解決呢?
其實這個問題已經通過微軟官方確認,是IE10的Bug,其實也能夠認爲是ASP.NET 2.0、3.五、4.0的Bug,因這些版本都沒法識別 IE10的User-Agent。微軟專門發佈了HOTFIX來修復這個問題:
碼農單位的不少Windows服務器都會自動更新安裝補丁,因此場景2中說的其它地市使用正常,實際上是由於這些服務器已經打上了補丁,一些新上架、重裝系統的服務器或自動更新沒有設置的服務器就極可能會出現這類問題。。。
若是對服務器沒有操做權限或者不想打補丁這麼麻煩,好比碼農我,也能夠在網站的根目錄,新增一個瀏覽器定義文件,步驟以下:
一、添加一個"App_Browsers"文件夾 ;
二、添加一個"*.browser"後綴的文件,如 IE10.browser;
三、在文件中添加以下內容(下面的配置表示,對全部的設備和瀏覽器,都支持Cookies):
<browsers>
<browser refID="Default">
<capabilities><!-- To avoid wrong detections of e.g. IE10 -->
<capability name="cookies" value="true" />
<capability name="ecmascriptversion" value="3.0" />
</capabilities>
</browser>
</browsers>
這是針對某個站點的配置,若是既不想打補丁又想對服務器上的全部站點作全局配置,要如何處理呢?很容易,其實上面已經明示,問題是出在ie.browser 這個文件的配置上,因此咱們只需在原來的基礎上,加上這一串 "\d{2,}$",使ASP.NET 能識別IE10的User-Agent就能夠了。修改後的配置以下:
<capability name="majorversion" match="^[6-9]|\d{2,}$" />
修改完後,再到命令行下將修改後的 .browser 文件編譯成程序集並安裝到GAC中,若是是Windows Server 200八、Win7,要以管理員身份運行命令行:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regbrowsers.exe -i
若是是IE11,因爲其User-Agent "Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko" 變化更大,因此需把下面這串加入來作匹配:
<!-- Mozilla/5.0 (Windows NT 6.3; Trident/7.0; rv:11.0) like Gecko -->
<browser id="IE11Preview" parentID="Mozilla">
<identification>
<userAgent match="Trident/(?'layoutVersion'\d+).*rv:(?'revision'(?'major'\d+)(\.(?'minor'\d+)?))" />
<userAgent nonMatch="MSIE" />
</identification>
<capabilities>
<capability name="browser" value="IE" />
<capability name="layoutEngine" value="Trident" />
<capability name="layoutEngineVersion" value="${layoutVersion}" />
<capability name="isColor" value="true" />
<capability name="screenBitDepth" value="8" />
<capability name="ecmascriptversion" value="3.0" />
<capability name="jscriptversion" value="6.0" />
<capability name="javascript" value="true" />
<capability name="javascriptversion" value="1.5" />
<capability name="w3cdomversion" value="1.0" />
<capability name="ExchangeOmaSupported" value="true" />
<capability name="activexcontrols" value="true" />
<capability name="backgroundsounds" value="true" />
<capability name="cookies" value="true" />
<capability name="frames" value="true" />
<capability name="javaapplets" value="true" />
<capability name="supportsCallback" value="true" />
<capability name="supportsFileUpload" value="true" />
<capability name="supportsMultilineTextBoxDisplay" value="true" />
<capability name="supportsMaintainScrollPositionOnPostback" value="true" />
<capability name="supportsVCard" value="true" />
<capability name="supportsXmlHttp" value="true" />
<capability name="tables" value="true" />
<capability name="supportsAccessKeyAttribute" value="true" />
<capability name="tagwriter" value="System.Web.UI.HtmlTextWriter" />
<capability name="vbscript" value="true" />
<capability name="revmajor" value="${major}" />
<capability name="revminor" value="${minor}" />
</capabilities>
</browser>
三板斧搞定!
幸福來的就是這麼忽然~~~