前言 近期專案需要對瀏覽器進行相容性檢查,確保使用者在不支援的瀏覽器上能獲得適當的提示或導向升級,依據不同的 browser 決定相應的處理方式。
一、探測作法 每有 Browser 會有不同的 User-Agent 內容,User-Agent 是可以被修改抓不到真正的瀏覽器,因此 HTML5 新增了 Client Hints 來提供更精確的瀏覽器資訊。 主要透過以下方式進行瀏覽器相容性檢查:
Client Hints :利用 navigator.userAgentData 取得更精確的瀏覽器資訊。
User-Agent :若 Client Hints 不支援,則回退使用 User-Agent 字串進行判斷。
1-1 Client Hints vs User-Agent
特性
Client Hints
User-Agent
精確度
高,能區分 Brave、Chromium 等
低,無法區分特殊瀏覽器等
可修改性
低,較難偽造
高,容易被修改
支援度
逐漸普及,現代瀏覽器多數支援
廣泛支援,所有瀏覽器皆支援
資訊豐富度
提供品牌、版本等詳細資訊
提供基本的瀏覽器名稱與版本
使用場景
需要高精度識別瀏覽器時
兼容性檢查、基本瀏覽器識別
1-2 使用方式 1-2-1 Client Hints 範例 1 2 3 navigator.userAgentData .brands .forEach ((brand ) => { console .log (`${brand.brand} : ${brand.version} ` ); });
1-2-3 User-Agent 範例 1 2 const userAgent = navigator.userAgent ;console .log (userAgent);
二、 Angular Line Browser Line Browser 在國內使用率極高,如果要讓 Line Browser 可以點開後,打出 Default Browser 必須要用到 Line 官方的 Search Params 作法。 之前透過 Grok AI Agent 抓取 Browser 是否支援 Client Hints 的功能,可以透過下方網址驗證效果 :
2-1 Client Hints 回應內容範本 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 { "brands" : [ { "brand" : "Chromium" , "version" : "140" } , { "brand" : "Not=A?Brand" , "version" : "24" } , { "brand" : "Google Chrome" , "version" : "140" } ] , "mobile" : false , "platform" : "Windows" , "architecture" : "x86" , "bitness" : "64" , "model" : "" , "platformVersion" : "19.0.0" , "uaFullVersion" : "140.0.7339.80" , "wow64" : false }
三、實作方式 定義平台、Browser 平台、版本等列舉與介面,並提供預設的支援版本設定。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 export enum SupportedBrowser { CHROME = "chrome" , FIREFOX = "firefox" , SAFARI = "safari" , EDGE = "edge" , SAMSUNG = "samsung" , LINE = "line" , UNKNOWN = "unknown" , } export enum Platform { DESKTOP = "desktop" , MOBILE = "mobile" , UNKNOWN = "unknown" , } export interface BrowserCompatibilityConfig { enabled : boolean ; supportedVersions : { chrome : string ; firefox : string ; safari : string ; edge : string ; samsung : string ; }; } export interface BrowserInfo { name : BrowserType ; version : string ; platform : Platform ; isSupported : boolean ; minimumVersion : string | null ; userAgent : string ; }
Client Hints 與 User-Agent 偵測邏輯,並進行版本比對與支援判斷。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 private detectBrowserFromClientHints (): { name : BrowserType ; version : string ; } | null { try { const navigator = this .windowRef .nativeWindow .navigator as any ; if (navigator.userAgentData && navigator.userAgentData .brands ) { const brands = navigator.userAgentData .brands ; for (const brand of brands) { } const chromiumBrand = brands.find ((b : any ) => b.brand .toLowerCase ().includes ('chromium' ) ); if (chromiumBrand) { return { name : SupportedBrowser .UNKNOWN , version : chromiumBrand.version , }; } } return null ; } catch (error) { console .warn ('Client Hints detection failed:' , error); return null ; } } private detectBrowser (userAgent : string ): { name : BrowserType ; version : string ; } { const supportedBrowserDetectors = [ { condition : () => (userAgent.includes ('Chrome' ) || userAgent.includes ('Safari' )) && !userAgent.includes ('Edg' ) && !userAgent.includes ('OPR' ) && !userAgent.includes ('SamsungBrowser' ) && !userAgent.includes ('Brave' ) && userAgent.includes ('Line' ), browser : SupportedBrowser .LINE , versionRegex : /Line\/(\d+\.\d+\.\d+)/ , }, ]; for (const detector of supportedBrowserDetectors) { if (detector.condition ()) { const match = userAgent.match (detector.versionRegex ); const version = detector.customVersionProcessor ? detector.customVersionProcessor (match) : match ? match[1 ] : '0.0.0' ; return { name : detector.browser , version }; } } return { name : SupportedBrowser .UNKNOWN , version : '0.0.0' }; }
最後要將 Line Browser 自動打開 Default Browser 的功能僅加入 openExternalbrowser=1 即可
1 2 3 4 5 6 7 8 9 10 11 12 if (browserInfo.name === SupportedBrowser .LINE ) { const url = this .windowRef .nativeWindow .location .href ; const targetUrl = new URL (url, window .location .origin ); targetUrl.searchParams .set ('openExternalBrowser' , '1' ); this .windowRef .nativeWindow .location .replace (targetUrl.toString ()); setTimeout (() => { this .showIncompatibleBrowserError (browserInfo); }, 3000 ); return ; }
四、結語 透過本模組的設計與實作,我們能夠有效地檢測並處理不同瀏覽器的相容性問題,特別是在行動裝置上使用 LINE 瀏覽器時,能夠自動引導用戶至預設瀏覽器,提升使用者體驗。未來可持續擴充支援更多瀏覽器及版本,並結合其他功能如 A/B 測試、升級提示等,進一步優化整體系統的穩定性與可用性。