2

【茶包射手日記】IE11 User Agent 問題

 2 years ago
source link: https://blog.darkthread.net/blog/ie-user-agent-study/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

【茶包射手日記】IE11 User Agent 問題-黑暗執行緒

IE 都更持續進行中,現階段有部分網頁需同時支援 IE、Edge、Chrome,甚至要區別 IE 文件模式決定回傳 HTML5 或是 IE Only 內容。

目前會遇到的 IE 清一色都是 IE11,只差在會切換不同的文件模式(如下圖),而文件模式主要由 HTML 中的 <meta http-equiv="x-ua-compatible" content="IE=N"> 控制。當 IE=Edge,由 F12 可觀察到文件模式的預設值為 11:

Fig1_637938395492712661.png

X-UA-Compatible 會改變 UserAgent,一般在伺服器端會用它判斷 IE 模式:

var m = Regex.Match(Request.UserAgent, "MSIE (?<n>[0-9]+)");
if (!m.Success) {
    //IE=Edge, HTML5
}
else {
    var ieVer = int.Parse(m.Groups["n"].Value);
    //ieVer = 5, 7, 8, 9, 10
}

依我的認知,若網頁有加 <meta http-equiv="x-ua-compatible" content="IE=Edge">,除非使用者開 F12 強制改模式,否則 UserAgent 應為 Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko,程式可依此判斷傳回 IE-Only 或 HTML5 內容。

不料,接獲通報部分使用者的 IE11 在 X-UA-Compatible IE=Edge 時仍看到 IE-Only 內容。

調查過程,先發現一件事:IE11 跟著作業系統,不同版本的 Windows 10,IE11 版本不同,行為可能存在小差異 (登楞!)。

隨意抽樣一些 Windows 10 LTSC 的 IE11,有 1607 (OS Build 14393.5192)、1809 (OS Build 11763.3046)、1909 (OS Build 18363.1734)... 等版號。我自己的 1909 機器沒問題,而能重現問題的兩台機器剛好都是 1607,在 X-UA-Compatible IE=Edge 時,傳送的 UserAgent 卻是 Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 10.0; WOW64; Trident/7.0; .NET4.0C; .NET4.0E; .NET CLR 2.0.50727; .NET CLR 3.0.30729; .NET CLR 3.5.30729)。於是,這很容易導出「問題出在 1607 IE11 版本」的推論。但科學辦案講求大膽假設,小心求證,繼續再試了幾台機器,發現另一台 1809 也觀察到 compatible; MSIE 7.0;, 1607 幸獲不在場證明,無保請回。(也幸好夠謹慎,沒有草率下結論砸了招牌。)

進一步推敲,想到另一個可能 - 相容性檢視設定!

用個實驗驗證,開啟 IE11 連上 User Agent String.Com,正常情況下會判定為 IE11:

Fig2_637938395493623652.png

動個手腳將 useragentstring.com 加入相容性檢視網站清單:

Fig3_637938395494188673.png

IE11 便會被識別成 IE7,跟我程式遇到的狀況一樣:

Fig4_637938395494870939.png

但要注意,上面所說的 UserAgent 指的是伺服器端接受到瀏覽器資訊,前端 JavaScript 讀取到的 navigator.userAgent 及實際文件模式仍由 <meta http-equiv="x-ua-compatible" content="IE=*"> 決定,用以下 ASP.NET 來驗證:

<%@Page Language="C#"%>
<!DOCTYPE html>
<html>
	<head>
		<meta http-equiv="x-ua-compatible" content="IE=Edge">
		<style>
			div { font-size: 9pt; font-family: Consolas; }
			span { color: purple; }
		</style>
	</head>
	<body>
		<div>Server UserAgent = <span><%=Request.UserAgent%></span></div>
		<div>Client userAgent = <span id=ua></span></div>
		<div>msCrypto = <span id=crypto></span></div>
		<script>
			document.getElementById('ua').innerText = navigator.userAgent;
			document.getElementById('crypto').innerText = window.msCrypto; //IE11 才支援的 API
		</script>
	</body>
</html>

故意將網站加入相容性檢視網站清單 (1),ASP.NET 端收到的 Request.UserAgent 變成 MSIE 7.0 (2),但如果回傳 <meta http-equiv="x-ua-compatible" content="IE=Edge">(3),IE 仍會以其為準切成 IE11 文件模式 (4),JavaScript 讀取的也是 IE11 的 navigator.userAgent (5)。

Fig5_637938395495454481.png

這個發現,打破了『當遇到舊 IE 相容模式要配合輸出 IE Only 內容』的迷思,若網頁己改為適用 IE11 的 HTML5 版本,即使 IE 將網站設成相容性檢視,我們仍可無視傳入的 UserAgent 內容,透過 X-UA-Compatible IE=Edge 強迫設定 IE 文件模式,大方顯示 HTML5 內容。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK