你是否遇到過當使用一個涉及到Cookie操作的網(wǎng)站或者管理系統(tǒng)時,IE 6、7、8、9下都跑的好好的,唯獨到了IE10、11這些高版本瀏覽器就不行了?好吧,這個問題碼農(nóng)連續(xù)2天內(nèi)遇到了2次。那么,我們就來看看,這個問題的前因后果。
先說下這2次的使用場景,一次是在某頁面中,先存Cookie,然后再入庫記錄相關(guān)數(shù)據(jù),但是發(fā)布到生產(chǎn)環(huán)境后,入庫操作沒有發(fā)生;后來通過打印日志發(fā)現(xiàn)問題卡在這里:
if (Request.Browser.Cookies)
也就是說,在客戶端是IE10的環(huán)境下,這里返回False!納尼,IE10默認配置下不支持Cookie?微軟你玩我的吧。
第二次是某地市的升級測試,在IE10的環(huán)境下,自服務(wù)網(wǎng)站登錄失敗;這個問題很奇怪,因為之前已經(jīng)升級過多個地市了,IE10使用都正常。這極大的引起了碼農(nóng)的興趣,由此引出了此文。
描述完場景,我們就來分析分析。雖然直覺告訴碼農(nóng),可能是Cookie的讀取或?qū)懭胗袉栴},但畢竟直覺這玩意兒不靠譜,咱還是得用事實和證據(jù)說話。國際慣例,先抓個HTTP包瞧瞧:

上圖是IE10下登錄失敗時,服務(wù)端返回的HTTP響應(yīng)頭;下圖是其它瀏覽器正常登錄時,服務(wù)端返回的HTTP響應(yīng)頭,注意紅色框框標注部分;

導(dǎo)致問題的直接原因,很清晰了吧:服務(wù)器響應(yīng)請求時,沒有回發(fā) Set-Cookie 頭,沒有這個頭,客戶端瀏覽器就無法寫入Cookie。所以基于Form認證(在Cookie中會存入加密票據(jù))的自服務(wù)網(wǎng)站,會無法登錄。
這時,你可能會覺得奇怪了,為啥只有IE10、IE11 會這樣,其它IE瀏覽器跑的妥妥的呢?嗯,為了滿足你的好奇心,我們繼續(xù)分析。
如果你的機器上裝了.NET的FrameWork,打開這個目錄 C:/Windows/Microsoft.NET/Framework/v4.0.30319/Config/Browsers。科普下,文件夾里面的.browser文件是全局訪問的,用于標識發(fā)出請求的瀏覽器,并標識這些瀏覽器具備的功能。如果要做定制修改(比如針對特定移動設(shè)備),只需把相應(yīng)的.browser文件復(fù)制到應(yīng)用程序的/App_Browsers文件夾中修改即可。先用記事本打開 ie.browser 這個文件,

注意圖中標注為紅色部分的正則表達式;然后再來看看,微軟公布的IE10的User-Agent:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.1; Trident/6.0),MSIE版本號由以前的1位數(shù)字(5-9)變成了現(xiàn)在的2位數(shù)字(10),很明顯,無法匹配上面的正則了吧。所以,由于無法正確識別IE10的User-Agent,所以ASP.NET把它看做是未知的瀏覽器,認為它不支持Cookie,由此而產(chǎn)生了一系列與Cookie相關(guān)的問題。
問題的根本總算是知道了,那么該如何解決呢?
其實這個問題已經(jīng)經(jīng)過微軟官方確認,是IE10的Bug,其實也可以認為是ASP.NET 2.0、3.5、4.0的Bug,因這些版本都無法識別 IE10的User-Agent。微軟專門發(fā)布了HOTFIX來修復(fù)這個問題:
碼農(nóng)單位的很多Windows服務(wù)器都會自動更新安裝補丁,所以場景2中說的其它地市使用正常,其實是因為這些服務(wù)器已經(jīng)打上了補丁,一些新上架、重裝系統(tǒng)的服務(wù)器或自動更新沒有設(shè)置的服務(wù)器就很可能會出現(xiàn)這類問題。。。 如果對服務(wù)器沒有操作權(quán)限或者不想打補丁這么麻煩,比如碼農(nóng)我,也可以在網(wǎng)站的根目錄,新增一個瀏覽器定義文件,步驟如下:
1、添加一個"App_Browsers"文件夾;
2、添加一個"*.browser"后綴的文件,如 IE10.browser;
3、在文件中添加如下內(nèi)容(下面的配置表示,對所有的設(shè)備和瀏覽器,都支持Cookies):
<browsers> <browser refID="Default"> <capabilities><!-- To avoid wrong detections of e.g. IE10 --> <capability name="cookies" value="true" /> <capability name="ecmascr這是針對某個站點的配置,如果既不想打補丁又想對服務(wù)器上的所有站點做全局配置,要如何處理呢?很容易,其實上面已經(jīng)明示,問題是出在ie.browser 這個文件的配置上,所以我們只需在原來的基礎(chǔ)上,加上這一串 "/d{2,}$",使ASP.NET 能識別IE10的User-Agent就可以了。修改后的配置如下:
<capability name="majorversion" match="^[6-9]|/d{2,}$" />修改完后,再到命令行下將修改后的 .browser 文件編譯成程序集并安裝到GAC中,如果是Windows Server 2008、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="IE11javascript" 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>
三板斧搞定!
幸福來的就是這么突然~~~
新聞熱點
疑難解答