【茶包射手日記】IE11 User Agent 問題
0 |
IE 都更持續進行中,現階段有部分網頁需同時支援 IE、Edge、Chrome,甚至要區別 IE 文件模式決定回傳 HTML5 或是 IE Only 內容。
目前會遇到的 IE 清一色都是 IE11,只差在會切換不同的文件模式(如下圖),而文件模式主要由 HTML 中的 <meta http-equiv="x-ua-compatible" content="IE=N">
控制。當 IE=Edge,由 F12 可觀察到文件模式的預設值為 11:
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:
動個手腳將 useragentstring.com 加入相容性檢視網站清單:
IE11 便會被識別成 IE7,跟我程式遇到的狀況一樣:
但要注意,上面所說的 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)。
這個發現,打破了『當遇到舊 IE 相容模式要配合輸出 IE Only 內容』的迷思,若網頁己改為適用 IE11 的 HTML5 版本,即使 IE 將網站設成相容性檢視,我們仍可無視傳入的 UserAgent 內容,透過 X-UA-Compatible IE=Edge 強迫設定 IE 文件模式,大方顯示 HTML5 內容。
Study of user agent behavior of IE under compatible view and different document modes.
Comments
Be the first to post a comment