前端判断浏览器名称以及版本号

2,933 阅读3分钟

基本上每个浏览器厂商都会在浏览器信息中展示自己唯一的标识,用来准确的区分不同浏览器,毕竟现在浏览器太卷了,都大同小异,浏览器提供的相关的api:navigator.userAgent 和 navigator.userAgentData用来获取浏览的相关信息

navigator.userAgent

按照标准的规范,浏览器的信息会以:浏览器标识/版本号的方式返回(少数浏览器例外),例如 Chrome/106.0.0.0

浏览器navigator.userAgent标识备注
chromeMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36chrome大部分浏览器都有chrome
firefoxMozilla/5.0 (Windows NT 10.0; Win64; x64; rv:105.0) Gecko/20100101 Firefox/105.0firefox
edgeMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/106.0.0.0 Safari/537.36 Edg/106.0.1370.42edg
safariMozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2safari有safari 无chrome
operaopr
世界之窗theworld
遨游maxthon最新版本被去掉了
QQ浏览器Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36 Core/1.94.178.400 QQBrowser/11.2.5170.400qqbrowser 或者 mqqbrowser
360浏览器Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36 QIHU 360SE360ee 或者 360se最新版本被去掉了
搜狗浏览器metasr
uc浏览器ubrowse
猎豹lbbrowser
微信浏览器micromessenger
小米miuibrowser
百度baidu
F1浏览器yunhai
23452345explorer
IE11trident 和 rv:11.0
IE10compatible 和 msie 10.0
IE9compatible 和 msie 9.0
IE8compatible 和 msie 8.0
IE7compatible 和 msie 7.0

navigator.userAgentData

此api返回浏览器系统相关的三个属性, 不同浏览器返回的信息各不相同

😹 此方法需要注意的是,如果网站以ip访问它返回的结果是undefined,应该是浏览器做了限制

以chrome浏览器为例

{
    brands: [
        {
            "brand": "Chromium",
            "version": "106"
        },
        {
            "brand": "Google Chrome",
            "version": "106"
        },
        {
            "brand": "Not;A=Brand",
            "version": "99"
        }
    ],
    mobile: false,
    platform: "Windows"
}

chrome和safari浏览器的判断

chrome和safari是两个比较主流的浏览器,他们的标识在很多浏览器的用户代理信息中都有返回,所有判断时需要有所区分

判断chrome浏览器不能简单的看用户代理信息里面是否有chrome字符串,很多其他浏览器器都是基于chrome进行二开的,也会带有这个字段

const isChrome = navigator.userAgentData?.brands?.some((item) => item.brand === 'Google Chrome')

判断safari浏览器也不能简单的判断是否携带safari字符串,因为包括chrome和其他浏览器基本也都会带这个字段

const u = navigator.userAgent.toLowerCase()
const isSafari = u.indexOf('safari') > -1 && u.indexOf('chrome) === -1

获取浏览器名称和版本号

通过各自浏览器唯一的标识进行判断,可以获取浏览器名称和版本号, 但是某些浏览器的信息不会带唯一性的标识,需要进行特殊的判断处理,以下方法可以判断下面所列出的所有浏览器

const browserList = [
  {
    bs_name: "火狐浏览器",
    bs_tag: "firefox",
  },
  {
    bs_name: "edge浏览器",
    bs_tag: "edg",
  },
  {
    bs_name: "opera",
    bs_tag: "opr",
  },
  {
    bs_name: "世界之窗",
    bs_tag: "theworld",
  },
  {
    bs_name: "遨游",
    bs_tag: "maxthon",
  },
  {
    bs_name: "QQ浏览器",
    bs_tag: "qqbrowser",
  },
  {
    bs_name: "360浏览器",
    bs_tag: "360",
  },
  {
    bs_name: "搜狗浏览器",
    bs_tag: "metasr",
  },
  {
    bs_name: "uc浏览器",
    bs_tag: "ubrowse",
  },
  {
    bs_name: "猎豹",
    bs_tag: "lbbrowser",
  },
  {
    bs_name: "微信浏览器",
    bs_tag: "micromessenger",
  },
  {
    bs_name: "小米浏览器",
    bs_tag: "miuibrowser",
  },
  {
    bs_name: "百度浏览器",
    bs_tag: "baidu",
  },
  {
    bs_name: "2345浏览器",
    bs_tag: "2345explorer",
  },
  {
    bs_name: "IE浏览器",
    bs_tag: "msie",
  },
  {
    bs_name: "IE11浏览器",
    bs_tag: "rv:11.0",
  },
];
const userAgent = navigator.userAgent.toLowerCase();
const userAgentData = navigator.userAgentData || { brands: [] };

// 通过浏览器标识获取浏览器版本号
const getBsVersion = (tag) => {
  const browser = userAgent
    .split(" ")
    .find((item) => item.indexOf(tag) > -1)
    .split("/");
  return browser[1] || getBsVersion("chrome");
};

// 判断是否是遨游浏览器
const isMaxthon = () => {
  return window.maxthon;
};

// 判断是否是360浏览器,简单通过浏览器信息无法判断
const is360 = () => {
  const result = false;
  for (var key in navigator.plugins) {
    if (navigator.plugins[key].filename == "internal-nacl-plugin") {
      return !result;
    }
  }
  return result;
};

// 获取浏览器信息
const getBsInfo = (list = []) => {
  if (isMaxthon()) {
    return {
      bs_name: "遨游浏览器",
      bs_tag: "maxthon",
      bs_version: getBsVersion("chrome"),
    };
  }
  if (userAgentData.brands.some((item) => item.brand === "Google Chrome")) {
    return {
      bs_name: "chrome浏览器",
      bs_tag: "chrome",
      bs_version: getBsVersion("chrome"),
    };
  }
  if (userAgent.indexOf("safari") > -1 && userAgent.indexOf("chrome") === -1) {
    return {
      bs_name: "safari浏览器",
      bs_tag: "safari",
      bs_version: getBsVersion("safari"),
    };
  }
  const isBrowser = browserList
    .concat(list)
    .find((item) => userAgent.indexOf(item.bs_tag) > -1);
  if (isBrowser) {
    return {
      bs_name: isBrowser.bs_name,
      bs_tag: isBrowser.bs_tag,
      bs_version: getBsVersion(isBrowser.bs_tag),
    };
  } else {
    if (is360()) {
      return {
        bs_name: "360浏览器",
        bs_tag: "360",
        bs_version: getBsVersion("chrome"),
      };
    }
    return {
      bs_name: "未知浏览器",
      bs_tag: "other",
      bs_version: "",
    };
  }
};

获取系统名称

function getOS() {
    var u = navigator.userAgent;
    if (!!u.match(/compatible/i) || u.match(/Windows/i)) {
        return 'windows';
    } else if (!!u.match(/Macintosh/i) || u.match(/MacIntel/i)) {
        return 'macOS';
    } else if (!!u.match(/iphone/i) || u.match(/Ipad/i)) {
        return 'ios';
    } else if (!!u.match(/android/i)) {
        return 'android';
    } else {
        return 'other';
    }
}

模块使用

为了方便使用,以上代码已封装为模块发布到npm

安装

npm i browser-tag -S

使用

import getBsInfo from "browser-tag";
const bsInfo = getBsInfo(); //  { bs_name: "chrome浏览器", bs_tag: "chrome", bs_version: "108.0.0.0" },