最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析JavaScript如何使用User-Agent精準(zhǔn)獲取瀏覽器與操作系統(tǒng)信息

 更新時間:2026年03月16日 08:27:24   作者:越重天  
本文介紹了一個輕量級User-Agent解析函數(shù)的實現(xiàn)方案,能夠精準(zhǔn)識別主流瀏覽器和操作系統(tǒng)信息,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下

在 Web 開發(fā)中,User-Agent(簡稱 UA)字符串是我們識別客戶端環(huán)境的重要入口。無論是用于流量統(tǒng)計、功能降級、A/B 測試,還是為不同設(shè)備提供定制化體驗,準(zhǔn)確獲取瀏覽器的名稱、版本以及操作系統(tǒng)的類型、版本都是一項基礎(chǔ)且高頻的需求。然而,UA 字符串的格式并非一成不變,不同瀏覽器、不同操作系統(tǒng)甚至同一瀏覽器的不同版本都可能攜帶不同的標(biāo)識,這給手動解析帶來了挑戰(zhàn)。很多開發(fā)者自己編寫的解析函數(shù)在面對現(xiàn)代瀏覽器(如 Edge、HeadlessChrome)或桌面操作系統(tǒng)(如 macOS、Linux)時,往往只能返回 unknown。本文將帶你從零構(gòu)建一個健壯、可擴展的 UA 解析函數(shù),能夠精準(zhǔn)識別主流瀏覽器和操作系統(tǒng),并兼顧移動設(shè)備和老式瀏覽器的兼容性。

1. 為什么要手動解析 User-Agent

雖然社區(qū)中有許多成熟的 UA 解析庫(如 ua-parser-js),但在某些場景下,我們?nèi)韵M约簩崿F(xiàn)一個輕量級、無依賴的版本:

  • 項目體積敏感:避免引入第三方庫,減少打包體積。
  • 定制化需求:需要按照特定規(guī)則提取或格式化信息。
  • 學(xué)習(xí)目的:深入理解 UA 結(jié)構(gòu)和各瀏覽器的標(biāo)識特點。
  • 簡單場景:只需識別少量常用環(huán)境,無需復(fù)雜庫。

手動解析的核心挑戰(zhàn)在于:UA 字符串中混雜著多種標(biāo)識,且不同瀏覽器放置版本號的位置各不相同。例如,Chrome 的版本號在 Chrome/ 后,Safari 的版本號卻在 Version/ 后,而 IE11 則需要從 rv: 中提取。此外,操作系統(tǒng)的版本號可能用下劃線分隔(如 macOS 的 10_15_7),也可能直接用點號分隔。

2. 設(shè)計一個可靠的解析策略

我們的目標(biāo)是編寫一個函數(shù) getSysInfo(),返回一個包含 browserName、browserVersion、name(操作系統(tǒng)名稱)、version(操作系統(tǒng)版本)的對象。為了實現(xiàn)精準(zhǔn)解析,我們需要遵循以下設(shè)計原則:

2.1 瀏覽器解析:按優(yōu)先級匹配

不同瀏覽器可能會在 UA 中同時出現(xiàn)多個標(biāo)識(例如 Chrome 的 UA 中既有 Chrome/ 也有 Safari/)。因此,我們必須按照優(yōu)先級依次匹配,一旦匹配成功就停止后續(xù)匹配。

常見的瀏覽器標(biāo)識及其優(yōu)先級(從高到低):

  • FirefoxFirefox/版本號
  • Edge(Chromium 版)Edg/版本號(注意是 Edg 而非 Edge
  • Edge(舊版)Edge/版本號
  • ChromeChrome/版本號(HeadlessChrome 的 UA 中也會包含 Chrome/,所以可以一并匹配)
  • Safari:版本號位于 Version/版本號 后面,且 UA 中包含 Safari/(注意不要與 Chrome 混淆)
  • OperaOPR/版本號Opera/版本號
  • IE11:通過 Trident/rv:版本號 識別
  • IE 舊版MSIE 版本號

2.2 操作系統(tǒng)解析:從常見到少見

操作系統(tǒng)標(biāo)識通常出現(xiàn)在 UA 的開頭括號內(nèi)。我們按以下順序匹配主流系統(tǒng):

  • WindowsWindows NT 版本號
  • macOSMac OS X 版本號(版本號可能為 10_15_7 形式,需要將下劃線替換為點號)
  • iOSiPhone OS 版本號iPad; CPU OS 版本號
  • AndroidAndroid 版本號
  • LinuxLinux(通常無版本號)
  • 其他 Unix-like:如 FreeBSDOpenBSD

如果以上都不匹配,則回退到通用移動設(shè)備檢測(利用預(yù)定義的移動設(shè)備關(guān)鍵字列表),確保對老式功能機或小眾設(shè)備的覆蓋。

3. 完整代碼實現(xiàn)

以下是基于上述策略實現(xiàn)的 getSysInfo 函數(shù),包含詳細(xì)的注釋,可直接復(fù)制使用。

/**
 * 獲取系統(tǒng)信息(增強版)
 * 返回對象包含:
 *   browserName, browserVersion  - 瀏覽器名稱和版本
 *   name, version                - 操作系統(tǒng)名稱和版本
 */
function getSysInfo() {
    const ua = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) EdgiOS/144 Version/16.0 Safari/605.1.15".toLowerCase();
    const sys = {};
    // ---------- 瀏覽器解析 ----------
    // 瀏覽器標(biāo)識列表(按優(yōu)先級排列)
    const browserPatterns = [
        { name: 'firefox',      pattern: /firefox\/([\d.]+)/ },
        { name: 'edg',          pattern: /edg\/([\d.]+)/ },          // Chromium Edge
        { name: 'edge',         pattern: /edge\/([\d.]+)/ },         // Edge Legacy
        { name: 'chrome',       pattern: /chrome\/([\d.]+)/ },       // 包括 HeadlessChrome(仍含 chrome 標(biāo)識)
        { name: 'safari',       pattern: /version\/([\d.]+).*safari/ }, // Safari 版本通常在 version 字段
        { name: 'opera',        pattern: /(?:opera|opr)\/([\d.]+)/ },
        { name: 'msie',         pattern: /msie ([\d.]+)/ },
        { name: 'trident',      pattern: /trident.*rv:([\d.]+)/ }    // IE11
    ];
    for (const { name, pattern } of browserPatterns) {
        const match = ua.match(pattern);
        if (match) {
            sys.browserName = name;
            sys.browserVersion = match[1];
            break;
        }
    }
    // 未匹配到任何瀏覽器
    if (!sys.browserName) {
        sys.browserName = 'unknown';
        sys.browserVersion = 'unknown';
    }
    // ---------- 操作系統(tǒng)解析 ----------
    // 操作系統(tǒng)模式列表(按優(yōu)先級)
    const osPatterns = [
        // Windows
        { name: 'Windows', versionPattern: /windows nt ([\d.]+)/, versionTransform: (v) => v },
        // Mac OS X
        { name: 'Mac OS X', versionPattern: /mac os x ([\d_]+)/, versionTransform: (v) => v.replace(/_/g, '.') },
        // iOS (iPhone/iPad/iPod)
        { name: 'iOS', versionPattern: /(?:iphone|ipad|ipod).*?os ([\d_]+)/, versionTransform: (v) => v.replace(/_/g, '.') },
        // Android
        { name: 'Android', versionPattern: /android ([\d.]+)/, versionTransform: (v) => v },
        // Linux
        { name: 'Linux', versionPattern: /linux/, versionTransform: () => null }, // Linux 通常無版本號
        // 其他 Unix-like 系統(tǒng)(如 FreeBSD)
        { name: 'Unix', versionPattern: /(?:freebsd|openbsd|sunos)/, versionTransform: () => null }
    ];
    let osFound = false;
    for (const { name, versionPattern, versionTransform } of osPatterns) {
        const match = ua.match(versionPattern);
        if (match) {
            sys.name = name;
            sys.version = match[1] ? versionTransform(match[1]) : 'unknown';
            osFound = true;
            break;
        }
    }
    // 若未匹配到已知操作系統(tǒng),則回退到原有的移動設(shè)備檢測(保留原邏輯)
    if (!osFound) {
        // 原移動檢測邏輯(稍作簡化,保持兼容)
        const mobileReg = /(mobile|android|ucbrowser|ucweb|tiantian|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|iphone|ipod|ipad|iris|kindle|lge |maemo|midp|mmp|netfront|opera mobi|opera mini|palm os|palm|phone|pixi\/|pre\/|plucker|pocket|psp|series40|series60|symbian|treo|up\.browser|up\.link|vodafone|wap|windows ce|windows phone|xda|xiino|windows nt|windows).*?([\d.]+)/;
        const m = ua.match(mobileReg);
        if (m) {
            sys.name = m[1];
            sys.version = m[2];
        } else {
            // 嘗試前4字符匹配(原邏輯)
            const typeReg = /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|acer|acoo|acs\-|aiko|airn|alav|alca|alco|amoi|anex|anny|anyw|aptu|arch|argo|aste|asus|attw|audi|au\-m|aur |aus |avan|beck|bell|benq|bilb|bird|blac|blaz|brew|brvw|bumb|bw\-n|bw\-u|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|comp|cond|craw|dait|dall|dang|dbte|dc\-s|devi|dica|dmob|doco|dopo|ds12|ds\-d|el49|elai|eml2|emul|eric|erk0|esl8|ez[4-7]0|ezos|ezwa|ezze|fetc|fly\-|fly_|g1 u|g560|gene|gf\-5|g\-mo|go\.w|good|grad|grun|haie|hcit|hd\-m|hd\-p|hd\-t|hei\-|hipt|hita|hp i|hpip|hs\-c|htc\-|htc |htc_|htca|htcg|htcp|htcs|htct|http|huaw|hutc|i\-20|i\-go|i\-ma|i230|iac |iac\-|iac\/|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|jata|java|jbro|jemu|jigs|kddi|keji|kgt |kgt\/|klon|kpt |kwc\-|kyoc|kyok|leno|lexi|lg g|lg\/k|lg\/l|lg\/u|lg50|lg54|lg\-[a-w]|libw|lynx|m1\-w|m3ga|m50\/|mate|maui|maxo|mc01|mc21|mcca|m\-cr|merc|meri|mio8|mioa|mits|mmef|mo01|mo02|mobi|mode|modo|mot\-|mot |moto|motv|mozz|mt50|mtp1|mtv |mwbp|mywa|n10[0-2]|n20[2-3]|n300|n302|n500|n502|n505|n700|n701|n710|nec\-|nem\-|neon|netf|newf|newg|newt|nok6|noki|nzph|o2im|opti|opwv|oran|owg1|p800|pana|pand|pant|pdxg|pg13|pg\-[1-8]|pg\-c|phil|pire|play|pluc|pn\-2|pock|port|pose|prox|psio|pt\-g|qa\-a|qc07|qc12|qc21|qc32|qc60|qc\-[2-7]|i\-|qtek|r380|r600|raks|rim9|rove|rozo|s55\/|sage|sama|samm|sams|sany|sava|sc01|sch\-|scoo|scp\-|sdk\/|sec\-|sec0|sec1|se47|semc|send|seri|sgh\-|shar|sie\-|siem|sk\-0|sl45|slid|smal|smar|smb3|smit|smt5|soft|sony|sp01|sph\-|spv\-|spv |sy01|symb|t218|t250|t600|t610|t618|tagt|talk|tcl\-|tdg\-|teli|telm|tim\-|t\-mo|topl|tosh|ts70|tsm\-|tsm3|tsm5|tx\-9|up\.b|upg1|upsi|utst|v400|v750|veri|virg|vite|vk40|vk5[0-3]|vk\-v|vm40|voda|vulc|vx52|vx53|vx60|vx61|vx70|vx80|vx81|vx83|vx85|vx98|w3c\-|w3c |webc|whit|wig |winc|winw|wmlb|wonu|x700|yas\-|your|zeto|zte\-/;
            const m2 = ua.substr(0, 4).match(typeReg);
            if (m2) {
                sys.name = "mobile[" + m2[0] + "]";
            } else {
                sys.name = 'unknown';
            }
            sys.version = 'unknown';
        }
    }
    return sys;
}

4. 測試與驗證

我們選取一些典型的 UA 字符串,驗證函數(shù)的解析結(jié)果:

User-Agent瀏覽器 (名稱, 版本)操作系統(tǒng) (名稱, 版本)
Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:140.0) Gecko/20100101 Firefox/140.0firefox, 140.0Mac OS X, 10.15
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36chrome, 145.0.0.0Mac OS X, 10.15.7
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/142.0.0.0 Safari/537.36chrome, 142.0.0.0Linux, unknown
Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.7.4 Safari/605.1.15safari, 18.7.4Mac OS X, 10.15.7
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/145.0.7632.6 Safari/537.36chrome, 145.0.7632.6Linux, unknown
Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/144.0.0.0 Safari/537.36 Edg/144.0.3719.115edg, 144.0.3719.115Linux, unknown
Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/15.0 Mobile/15E148 Safari/604.1safari, 15.0iOS, 15.0

從測試結(jié)果可以看出,函數(shù)能夠正確識別:

  • 不同瀏覽器的名稱和版本(包括 Edge 的 edg 標(biāo)識)。
  • 主流操作系統(tǒng)的名稱,并對 macOS/iOS 的版本號做規(guī)范化處理(下劃線轉(zhuǎn)點號)。
  • 對于 Linux 等通常不報告版本的系統(tǒng),返回 unknown 版本,符合預(yù)期。

5. 總結(jié)

本文介紹的手動解析方法,通過合理的優(yōu)先級匹配和版本號規(guī)范化,實現(xiàn)了對主流瀏覽器和操作系統(tǒng)的精準(zhǔn)識別。該函數(shù)無外部依賴,代碼清晰,易于維護和擴展。在實際應(yīng)用中,你可以根據(jù)項目需求調(diào)整正則表達(dá)式或增加新的匹配規(guī)則(例如識別 Chrome iOS、Firefox iOS 等)。

當(dāng)然,UA 字符串本身是一個不可靠的輸入源,用戶可能修改或偽造。在安全性要求較高的場景下,請勿僅依賴 UA 做關(guān)鍵判斷。此外,隨著瀏覽器和操作系統(tǒng)的更新,新的標(biāo)識符可能不斷涌現(xiàn),建議定期測試并更新正則規(guī)則。

如果你需要覆蓋更廣泛的設(shè)備(包括智能電視、游戲機等),可以考慮將移動設(shè)備回退部分的正則替換為更完整的列表,或直接使用社區(qū)維護的 UA 解析庫。但無論如何,理解 UA 解析的內(nèi)部原理,都將有助于你更好地處理客戶端環(huán)境信息。

到此這篇關(guān)于淺析JavaScript如何使用User-Agent精準(zhǔn)獲取瀏覽器與操作系統(tǒng)信息的文章就介紹到這了,更多相關(guān)JavaScript User-Agent獲取瀏覽器與操作系統(tǒng)信息內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

攀枝花市| 华阴市| 焦作市| 葫芦岛市| 高要市| 进贤县| 林甸县| 额敏县| 新晃| 且末县| 那曲县| 安福县| 大宁县| 县级市| 隆子县| 乐山市| 塘沽区| 无为县| 湄潭县| 井陉县| 绥宁县| 武鸣县| 定兴县| 逊克县| 清流县| 高陵县| 安徽省| 延津县| 壤塘县| 自贡市| 汕头市| 高青县| 扎兰屯市| 泰州市| 喀什市| 东海县| 昌平区| 西畴县| 竹山县| 平利县| 汝南县|