為什麼 Edge 會在 User-Agent 裡加入「Safari」?

20 年前的瀏覽器戰爭留下的怪異遺產



在檢查伺服器日誌時,你可能會看到這樣的字串。

Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/101.0.4951.64
Safari/537.36
Edg/101.0.1210.47

「Edge 竟然還有 Safari?」 「Chrome 竟然還有 Mozilla?」

一個瀏覽器怎麼會同時裝扮成四個?

這不只是字串玩笑,而是網路歷史上最激烈的瀏覽器戰爭的化石。 而這場戰爭的餘波,到 2025 年仍在伺服器日誌中顯現

本文將說明:

  • 為什麼所有瀏覽器仍以 Mozilla/5.0 開頭
  • 為什麼 Chromium 基礎的 Edge 必須「抱著 Safari」
  • 這一亂象最終如何被標準淘汰

1. 一切始於 Netscape vs IE 的戰爭

1990 年代後期,瀏覽器市場幾乎只有兩個玩家:

  • Netscape Navigator
  • Internet Explorer

當時 Netscape 的 User-Agent 如下。

Mozilla/4.0 (compatible; ...)

問題從這裡開始。

網頁開發者就這樣想:

「Mozilla(=Netscape)瀏覽器就能用最新功能,其他就用舊版程式碼。」

也就是說,瀏覽器功能分支 = User-Agent 字串判斷

// 1990 年代(?)式偽碼
if (ua.includes("Mozilla")) {
  // Netscape / 現代瀏覽器用的「酷」功能
} else {
  // 低階版本
}

其他瀏覽器聽了就氣得要死。

「我們也跟 Netscape 一樣,為什麼要被歧視?」

於是大家都在 UA 前面加上 Mozilla。 這時的 Mozilla 其實是:

「我跟 Netscape 一樣,別把我當低階。」

“Mozilla” 名稱的由來:Godzilla 風格

  • “Mosaic + Godzilla” → “Mozilla” 這個說法很常見
  • 也帶有「像怪獸哥斯拉般強大的瀏覽器」的諧音

但實際上只是:

「Netscape 系列,或至少跟 Netscape 一樣好用」

這成了行銷與歷史標籤

結果,直到今天,幾乎所有瀏覽器都以這樣的 UA 開頭。

Mozilla/5.0 (Windows NT 10.0; Win64; x64; ...)

不是因為它真的「Mozilla」,而是因為 「我跟 Netscape 一樣,別把我當舊」 的歷史原因。


2. WebKit、Gecko、Trident… 引擎戰又添混亂



2000 年代初,瀏覽器引擎分成:

  • IE → Trident
  • Firefox → Gecko
  • Safari → WebKit

開發者又一次用 UA 來區分瀏覽器。

const ua = navigator.userAgent;

if (ua.includes("Safari")) {
  // Safari / WebKit 用的程式碼
}
if (ua.includes("Gecko")) {
  // Firefox 用的程式碼
}
if (ua.includes("Trident")) {
  // IE 專用程式碼(眼淚...)
}

這已經不是好模式。 引擎名稱與品牌名稱混在一起,分支邏輯越來越複雜。

Chrome 的出現 → 「你是誰?」危機

Chrome 首次出現時,問題很簡單:

網站不知道 Chrome,於是 UA 檢測把它送進「Safari」程式碼路徑。

Chrome 的策略是:

「那就裝扮成 Safari。」

最終 Chrome 的自我介紹如下。

Mozilla/5.0 (...)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/xx.xx.xx
Safari/537.36

這個字串的實際意義大致是:

  • Mozilla/5.0 → 「我跟 Netscape 一樣」
  • AppleWebKit/537.36 → 「渲染引擎是 WebKit 系列」
  • (KHTML, like Gecko) → 「能像 Gecko(Firefox)一樣運作」
  • Safari/537.36 → 「看起來像 Safari,確保相容」
  • Chrome/xx → 「實際瀏覽器是 Chrome」

也就是說,

「我既是 Mozilla,又是 WebKit,又能像 Gecko 一樣運作, 看起來像 Safari,實際身份是 Chrome。」

這就是 四重偽裝瀏覽器 的誕生。


3. Edge 的出現:身份與生存的妥協

現在輪到 Microsoft。最初的 Edge 使用自己的 EdgeHTML 引擎, 但最終轉向 Chromium 基礎 Edge

此時 Microsoft 最清楚的一件事:

「網站程式碼已經有數十萬處依賴 User-Agent 分支。」

如果 Edge 像這樣走:

User-Agent: Edge/101.0.0.0

現實會發生什麼?

  • 許多網站無法辨識 Edge
  • if (ua.includes("Chrome")) 等舊分支不會被觸發
  • 會出現「不支援此瀏覽器」的提示
  • 功能受限、排版破碎、奇怪的 polyfill…

也就是說,技術上雖然誠實,但會陷入相容性地獄

Edge 的策略

「身份是 Edge,但外觀必須像 Chrome + Safari 系列。」

因此我們看到的 UA 如下。

Mozilla/5.0 (Windows NT 10.0; Win64; x64)
AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/101.0.4951.64
Safari/537.36
Edg/101.0.1210.47

解讀:

  • Mozilla → 「我也是現代瀏覽器」
  • AppleWebKit → 「我會像 WebKit 一樣渲染」
  • Chrome → 「我基於 Chromium」
  • Safari → 「我看起來像 Safari,別阻止我」
  • Edg → 「但品牌是 Edge」

也就是說,這長字串不是 Edge 的自我介紹,而是 「為了與遺留程式碼妥協而設計的生存偽裝卡」。


4. User-Agent 字串解讀章:一行字串中的 30 年歷史

總結一下。 從剛才的 UA 中提取主要 token:

字串 實際意義(譯)
Mozilla/5.0 「我跟 Netscape 一樣,別把我當舊。」
AppleWebKit/537.36 「我像 Safari 一樣渲染,屬於 WebKit 系列。」
KHTML, like Gecko 「我能像 Gecko(Firefox)一樣運作。」
Safari/537.36 「我不是真正的 Safari,但看起來像,確保相容。」
Chrome/101.0... 「我的引擎是 Chromium(Chrome)基礎。」
Edg/101.0... 「品牌是 Edge,其他都是生存偽裝。」

一行字串中包含:

  • Netscape vs IE 瀏覽器戰爭
  • Gecko vs WebKit vs Trident 引擎戰
  • Chrome 的市場佔領過程
  • Edge 的生存策略與現實妥協

5. User-Agent 正在成為「歷史垃圾」

問題在於,這套 User-Agent 系統在今天已經是破舊設計

  • 瀏覽器互相偽裝 → 信任度 0
  • 與遺留程式碼妥協,字串不斷膨脹
  • 裝置/OS 資訊過度暴露 → 隱私問題
  • 透過 UA 解析準確判斷瀏覽器/功能已經幾乎不可能

因此 W3C 與瀏覽器供應商正逐步淘汰 UA 字串, 改用 User‑Agent Client Hints 的新方式。

Client Hints:現在該說實話

未來會有這些標頭成為主角。

Sec-CH-UA
Sec-CH-UA-Platform
Sec-CH-UA-Mobile

大致流程:

  1. 伺服器在回應標頭中請求「請告訴我你的瀏覽器資訊」
  2. 瀏覽器只傳送需要的資訊,結構化且可選
  3. 不再需要解析偽裝字串

優點:

  • 瀏覽器不必再「裝扮成 Safari 的 Chrome Edge」
  • 伺服器只拿到需要的資訊,隱私暴露減少
  • 用結構化資料取代字串解析,程式碼更簡潔

也就是說,瀏覽器正被設計得更誠實


6. 結語 — 重新看待伺服器日誌中的「怪異一行」

回到最初的那一行。

Mozilla/5.0 ... Safari/537.36 ... Edg/101

這不是簡單的字串組合。

  • 瀏覽器戰爭與霸權競爭
  • 與遺留程式碼的妥協
  • 市場佔有率的偽裝與策略
  • 以及標準正慢慢收拾的情況

所有這些都被壓縮成 一段小小的歷史紀錄

而有趣的是,

這段歷史風暴的殘渣,到 2025 年仍在伺服器日誌中每日被捕捉

下次你在伺服器日誌中看到 Mozilla/5.0 ... Safari ... Edg/... 這樣怪異組合時, 不妨想想「又一個化石經過」吧。 🙂

image