UserAgent 是什麼?網站如何用它辨識身分?
今天夏格飛要介紹的是網站相關從業人員一定會聽過的 UserAgent,它常常被用來辨識使用者的瀏覽器、裝置或作業系統。而若有看過網站存取記錄或伺服器 log 的人,一定也常常看到 UserAgent 的完整字串。這些 UserAgent 字串到底是什麼意思,如何判讀,讓我們一步一步來解析。
[toc]
什麼是 UserAgent
UserAgent 又稱使用者代理,是網站與伺服器用來辨識使用者行為的標記。所謂的使用者代理,意思是我們所操作的電腦、手機等裝置,以及上面用來瀏覽網頁的瀏覽器,其實是代理我們的身分去呼叫網站的終端程式,所以這些工具被稱為「代理」。
當使用者瀏覽網站時,瀏覽器 (也就是這個代理) 會根據當下的裝置類型、版本號、作業系統等資訊,產生一個 UserAgent 字串,每次瀏覽網頁時,就會帶著這個字串以 User-Agent
Header 的形式發送給伺服器,讓伺服器可以得知現在這個人使用的裝置的各類資訊。
發送出來的 Header 可能長這樣:
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36
其中,從裡面可以看到幾個資訊
Macintosh: 表示這是 Mac 電腦
Mac OS X 10_15_7: 表示作業系統為 OSX 10.15.7
Intel Mac: 表示是 Intel 晶片的 Mac
AppleWebKit: 瀏覽器核心使用 KHTML / WebKit
Chrome/127.0.0.0: 瀏覽器是 Chrome 的 127 版
如果您想看到自己的 UserAgent,可以造訪類似像 What's My User Agent 這樣的網站,快速看見自己的 UserAgent。
UserAgent 的由來
UserAgent 最早出現在 1996 年中的定義 (HTTP/1.0 的 RFC 1945),在這裡可以找出 UserAgent 的原始定義,其中包含 範例:
User-Agent: CERN-LineMode/2.15 libwww/2.17b3
在接下來十年期間,這個字串又累積了各種用戶端的附加資訊。例如 Chrome 目前的UserAgent 字串
Mozilla/5.0 (Linux; Android 10; Pixel 3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4076.0 Mobile Safari/537.36
延伸閱讀: 為什麼瀏覽器 user-agent string 總是包含 Mozilla/5.0 ?
UserAgent 有哪些形式
接下來我們再舉一些不同裝置與不同瀏覽器的 UserAgent 例子:
Android
Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36
Mozilla/5.0 (Linux; Android 13; Pixel 6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36
Mozilla/5.0 (Linux; Android 13; SM-S901B) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Mobile Safari/537.36
iPhone
Mozilla/5.0 (iPhone14,3; U; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/19A346 Safari/602.1
Mozilla/5.0 (iPhone13,2; U; CPU iPhone OS 14_0 like Mac OS X) AppleWebKit/602.1.50 (KHTML, like Gecko) Version/10.0 Mobile/15E148 Safari/602.1
平板
Mozilla/5.0 (Linux; Android 12; SM-X906C Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/80.0.3987.119 Mobile Safari/537.36
Mozilla/5.0 (Linux; Android 11; Lenovo YT-J706X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.45 Safari/537.36
Mozilla/5.0 (Linux; Android 7.0; Pixel C Build/NRD90M; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/52.0.2743.98 Safari/537.36
Windows 電腦
Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36 Edge/12.246
Mozilla/5.0 (X11; CrOS x86_64 8172.45.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/51.0.2704.64 Safari/537.36
Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/47.0.2526.111 Safari/537.36
搜尋引擎
Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
Mozilla/5.0 (compatible; bingbot/2.0; +http://www.bing.com/bingbot.htm)
Mozilla/5.0 (compatible; Yahoo! Slurp; http://help.yahoo.com/help/us/ysearch/slurp)
大抵上格式都很像,就是中間的裝置類型與瀏覽器等等資訊會更換。若是搜尋引擎,通常都會有一個 robot 或 bot 字串可以辨別。
UserAgent 的用途
UserAgent 既然可以辨識使用者的裝置類型與版本,那用途其實就非常廣,常見的有
依照裝置或瀏覽器提供不同功能
辨識裝置是電腦、平板還是手機,顯示不同版面
辨識是否是爬蟲,是否阻擋
了解使用者的操作系統與瀏覽器,協助軟體除錯用
分析使用者來源與行為,還有裝置與作業系統的市佔率...等等
在軟體研發上站了非常重要的地位。因為少了 UserAgent,就很難掌握使用者的輪廓與裝置類型,開發與除錯也會變得非常的困難。
如何用 UserAgent 辨識裝置資訊
我們提供一些簡單的方式判斷 UserAgent 提供的資訊
純 JS 寫法
判斷是否是手機
const toMatch = [
/Android/i,
/webOS/i,
/iPhone/i,
/iPad/i,
/iPod/i,
/BlackBerry/i,
/Windows Phone/i
];
const isMobile = toMatch.some((toMatchItem) => {
return navigator.userAgent.match(toMatchItem);
});
判斷瀏覽器
const isChrome = navigator.userAgent.includes("Chrome");
const isFirefox = navigator.userAgent.includes("Firefox");
const isSafari = navigator.userAgent.includes("Safari") && !isChrome;
更多請參考: How to detect the user browser ( Safari, Chrome, IE, Firefox and Opera ) using JavaScript ?
使用套件
使用套件是比較推薦的做法,畢竟裝置與版本號會持續更新,使用既有套件,會幫您維護好未來的所有狀況,您只要使用即可。
這邊用 ua-parser.js 做範例,可以輕鬆的取用眾多裝置資訊。
<script src="https://cdn.jsdelivr.net/npm/ua-parser-js/dist/ua-parser.min.js"></script>
<script>
const uap = new UAParser();
console.log(result.browser); // {name: "Chromium", version: "15.0.874.106", major: "15", type: undefined}
console.log(result.device); // {model: undefined, type: undefined, vendor: undefined}
console.log(result.os); // {name: "Ubuntu", version: "11.10"}
console.log(result.os.version); // "11.10"
console.log(result.engine.name); // "WebKit"
console.log(result.cpu.architecture); // "amd64"
</script>
UserAgent 的缺點
UserAgent 雖然可以提供裝置辨識的功能,但其實有很大缺點存在。
不是永遠都準確
雖然 UserAgent 會自動帶入裝置資訊,但這些裝置資訊其實沒有統一規範。工程師想怎麼寫就怎麼寫。所以以前曾有過平板電腦上送出的 UserAgent 寫成手機的案例,所以那個系列的平板瀏覽網站時,都被當成手機識別,可能會造成使用者的一些不便。
很多時候,某些參數可能也因為長年的歷史問題沒有修改,因此一直保留舊的參數。也有些裝置或瀏覽器會為了獲得其他瀏覽器的功能,故意偽裝成其他瀏覽器的 UserAgent。
可以偽造
UserAgent 是透過HTTP呼叫的 Header 送出的,這是一個可選選項,且任何人都可以自由修改,所以沒有強制性。稍微有技術經驗的人,很容易就可以換掉自己的 UserAgent,偽裝成不同的裝置與瀏覽器。
也有些人會故意送出錯誤格式的 UserAgent,可能造成網站分析錯誤而程式損壞,故而分析其漏洞加以侵入。
格式混亂
因為 UserAgent 的格式並不是標準定義的,而是長年的默契。所以很多時候都會有分析錯誤的狀況。大多數的網站與軟體,都依賴幾個常見的分析函式庫去處理這些格式,經常要為了某個沒寫好格式的瀏覽器或裝置,額外加特例,使得函式庫越來越臃腫,性能也越來越差。
另外,新推出的瀏覽器與裝置,也要等一段時間函式庫更新後,才能認得。當初瀏覽推出第一代 Edge 時,也是有許多函式庫尚未更新分析程式而無法辨識出來。
隱私問題與安全性
UserAgent 通常包含大量詳細的客戶端信息,包括瀏覽器版本、操作系統版本、設備類型等。這些信息可能會暴露用戶的隱私,尤其是當這些信息被追蹤器或第三方服務收集時,容易被用來進行用戶識別和追蹤。
UserAgent 的遺留問題
前面提到,我送出的 UserAgent 可能長這樣
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36
分析結果是:
Macintosh: 表示這是 Mac 電腦
Mac OS X 10_15_7: 表示作業系統為 OSX 10.15.7
Intel Mac: 表示是 Intel 晶片的 Mac
AppleWebKit: 瀏覽器核心使用 KHTML / WebKit
Chrome/127.0.0.0: 瀏覽器是 Chrome 的 127 版
但這個資訊有點奇怪,我的電腦明明是 Apple ARM Mac ,且作業系統早就是 14.3.1 Sonoma 了,為什麼會顯示舊版本呢?
這是 UserAgent 的遺留問題,由於 UserAgent 只是一個字串,網站們都要用字串分析程式把這組字串切開。但在 2020 年左右,當 Mac 升到 11 版時,全世界回報大量的網站掛點。因為當時許多 UserAgent 函式庫沒有預期會出現 11 以上的版本號,所以全部炸掉了。為此所有瀏覽器在偵測到 Mac 版本大於 11 時,都會自動把版號壓在 10.15.7,一直到現在,考量到很多網站可能都尚未更新,也就沒有再改回去了。
所以,包含前面的 Intel Mac 字串也是一樣為了相容性原因而不再修改,從 2020 年開始,UserAgent 就無法再偵測更新的Mac電腦型號與作業系統版本了。
Windows 也沒有比較好過,自從 Windows11 推出後,版號也被鎖在 10.0 不再往上升了。
這件事的相關網路討論
Cap the reported macOS version in the user-agent string at 10_15_7
Cap the User-Agent string's reported macOS version at 10.15 - Mozilla
替代技術: Sec-CH-UA
由於前面的這些問題已經困擾技術社群已久,故而催生了新的網路協定 Sec-CH-UA
。
Sec-CH-UA
是一系列全新的 HTTP 標頭 (header),可以替代 UserAgent 傳輸裝置資訊給網站或軟體。它的特色是將多個不同訊息區分開來,例如:
Sec-CH-UA: " Not A;Brand";v="99", "Chromium";v="96", "Google Chrome";v="96"
Sec-CH-UA-Arch: x86
Sec-CH-UA-Mobile: ?0
Sec-CH-UA-Platform: Windows
Sec-CH-UA-Platform-Version: 13.0.0
這使得瀏覽器可以限定只傳送必要的資訊給網站,而不像 UserAgent 一樣,要一口氣發送所有資訊的字串給伺服器。
目前 Sec-CH-UA 還在實驗階段,詳細用法可以參考 MDN 文件。
更詳細的介紹可以看我們的獨立介紹文章
結論
UserAgent 肯定是網際網路眾多活化石的其中一個了。隨著時間過去越來越複雜難懂的 UserAgent 字串,增加了分析與判斷的困難度。
但目前,UserAgent 依然是網路上非常重要的協定之一,眾多網站依賴他判斷裝置版面與分析裝置資訊,短期內難以被取代。或許主流瀏覽很想給他設定一退場時間,但可見的未來還不會立刻發生。
Subscribe to my newsletter
Read articles from Simon Asika directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by