作者:JowayYoung
仓库:Github、CodePen
博客:掘金、思否、知乎、简书、头条、CSDN
公众号:IQ前端
联系我:关注公众号后有我的微信
特别声明:原创不易,未经授权不得对此文章进行转载或抄袭,否则按侵权处理,如需转载或开通公众号白名单可联系我,希望各位尊重原创的知识产权

前言

看到标题,大家就能想起这个需求在很多项目上都能用到。我们部署在Web服务器上的前端应用,既可以用PC浏览器访问,也可以用手机浏览器访问,再加上现在智能设备的推广,我们甚至能在车载系统、穿戴设备和电视平台上访问。

设备的多样化让用户无处不在,有时候我们需要根据不同的浏览器运行环境做出对应的处理。浏览器是JavaScript的承载体,我们可以从浏览器上获取相关的信息,来进一步处理我们的业务逻辑。

然而浏览器品牌众多,有些浏览器使用的标准也不太一样,造就了难以统一的判断。下面我大概罗列一下常用的浏览器品牌和在什么情况下使用浏览器运行环境判断。浏览器相关统计数据可以参考这里。

国际五大浏览器品牌:按照全球使用率降序排列

  • Google ChromeWindowsMacOSLinuxAndroidiOS
  • Apple SafariMacOSiOS
  • Mozilla FirefoxWindowsMacOSLinuxAndroidiOS
  • ASA OperaWindowsMacOSLinuxAndroidiOS
  • Microsoft Internet ExplorerMicrosoft EdgeWindows

国产常用浏览器品牌:按照国内使用率降序排列,普遍基于开源项目Chromium进行开发

  • 微信浏览器
  • QQ浏览器
  • UC浏览器
  • 360浏览器
  • 2345浏览器
  • 搜狗浏览器
  • 猎豹浏览器
  • 遨游浏览器
  • 其他浏览器:很多很多,数不清,我就不列出来了

顺便吐槽一下这个不要脸的红芯浏览器,明明就是基于Chromium进行二次开发再套多一层外壳,还非得说自己开发的浏览器是世界第五大浏览器,偷吃不抹嘴,还是被眼尖的网友发现了。详情请戳one、two、three。。。。

使用场景

  • 判断用户浏览器是桌面端还是移动端,显示对应的主题样式
  • 判断用户浏览器是Android端还是iOS端,跳转到对应的App下载链接
  • 判断用户浏览器是微信端还是H5端,调用微信分享或当前浏览器分享
  • 获取用户浏览器的内核和载体,用于统计用户设备平台分布区间
  • 获取用户浏览器的载体版本,用于提示更新信息
  • 其实还有很多使用场景,就不一一举例了

原理

针对处理一个这样的使用场景,其实有一个比较专业的名字,叫做浏览器指纹。我们上面谈到的需求也只是浏览器指纹方案里面的一小部分,而我们需要使用到的浏览器指纹就是UserAgent

这个UserAgent是何方神圣呢,中文翻译过来就是用户代理。引用百度的定义,就是一个特殊字符串头,使得服务器能够识别客户使用的操作系统及版本、CPU类型、浏览器载体及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。而这些信息也足够我们去判断浏览器运行环境了。

准备

目前网上很多解决方法都只是针对系统是否是桌面端还是移动端,Android端还是iOS端,部分浏览器载体的判断和获取等等,没有一个比较完美或者终极的解决方案。

因此我用了很多测试平台整理出一个比较全面的解决方案。这个方案包含浏览器系统及版本、浏览器平台、浏览器内核及版本、浏览器载体及版本、浏览器外壳及版本。

而此方案也是基于navigator.userAgent获取相关浏览器信息(如下),再通过系统、平台、内核、载体、外壳的特有字段进行归类统一,整理出一个完整的浏览器运行环境。

const ua = navigator.userAgent.toLowerCase();// 输出
"mozilla/5.0 (iphone; cpu iphone os 11_0 like mac os x) applewebkit/604.1.38 (khtml, like gecko) version/11.0 mobile/15a372 safari/604.1"

浏览器信息:权重按照以下降序排列

  • 浏览器系统:所运行的操作系统,包含WindowsMacOSLinuxAndroidiOS
  • 浏览器平台:所运行的设备平台,包含Desktop桌面端、Mobile移动端
  • 浏览器内核:浏览器渲染引擎,包含WebkitGeckoPrestoTrident
  • 浏览器载体:五大浏览器品牌,包含ChromeSafariFirefoxOperaIExplore/Edge
  • 浏览器外壳:基于五大浏览器品牌的内核进行开发,再套一层自研技术的外壳,如国内众多浏览器品牌

获取UserAgent是否包含字段:判断是否包含系统、平台、内核、载体、外壳的特有字段

const testUa = regexp => regexp.test(ua);

获取UserAgent对应字段的版本

const testVs = regexp => ua.match(regexp).toString().replace(/[^0-9|_.]/g, "").replace(/_/g, ".");

方案

上述准备工作完成后,我们就按照权重(系统 + 系统版本 > 平台 > 内核 + 载体 + 内核版本 + 载体版本 > 外壳 + 外壳版本)根据系统、平台、内核、载体、外壳的特有字段来归类统一浏览器运行环境。

系统+系统版本

// 系统
let system = "unknow";
if (testUa(/windows|win32|win64|wow32|wow64/g)) {system = "windows"; // windows系统
} else if (testUa(/macintosh|macintel/g)) {system = "macos"; // macos系统
} else if (testUa(/x11/g)) {system = "linux"; // linux系统
} else if (testUa(/android|adr/g)) {system = "android"; // android系统
} else if (testUa(/ios|iphone|ipad|ipod|iwatch/g)) {system = "ios"; // ios系统
}// 系统版本
let systemVs = "unknow";
if (system === "windows") {if (testUa(/windows nt 5.0|windows 2000/g)) {systemVs = "2000";} else if (testUa(/windows nt 5.1|windows xp/g)) {systemVs = "xp";} else if (testUa(/windows nt 5.2|windows 2003/g)) {systemVs = "2003";} else if (testUa(/windows nt 6.0|windows vista/g)) {systemVs = "vista";} else if (testUa(/windows nt 6.1|windows 7/g)) {systemVs = "7";} else if (testUa(/windows nt 6.2|windows 8/g)) {systemVs = "8";} else if (testUa(/windows nt 6.3|windows 8.1/g)) {systemVs = "8.1";} else if (testUa(/windows nt 10.0|windows 10/g)) {systemVs = "10";}
} else if (system === "macos") {systemVs = testVs(/os x [\d._]+/g);
} else if (system === "android") {systemVs = testVs(/android [\d._]+/g);
} else if (system === "ios") {systemVs = testVs(/os [\d._]+/g);
}

平台

let platform = "unknow";
if (system === "windows" || system === "macos" || system === "linux") {platform = "desktop"; // 桌面端
} else if (system === "android" || system === "ios" || testUa(/mobile/g)) {platform = "mobile"; // 移动端
}

内核+载体

let engine = "unknow";
let supporter = "unknow";
if (testUa(/applewebkit/g)) {engine = "webkit"; // webkit内核if (testUa(/edge/g)) {supporter = "edge"; // edge浏览器} else if (testUa(/opr/g)) {supporter = "opera"; // opera浏览器} else if (testUa(/chrome/g)) {supporter = "chrome"; // chrome浏览器} else if (testUa(/safari/g)) {supporter = "safari"; // safari浏览器}
} else if (testUa(/gecko/g) && testUa(/firefox/g)) {engine = "gecko"; // gecko内核supporter = "firefox"; // firefox浏览器
} else if (testUa(/presto/g)) {engine = "presto"; // presto内核supporter = "opera"; // opera浏览器
} else if (testUa(/trident|compatible|msie/g)) {engine = "trident"; // trident内核supporter = "iexplore"; // iexplore浏览器
}

内核版本+载体版本

// 内核版本
let engineVs = "unknow";
if (engine === "webkit") {engineVs = testVs(/applewebkit\/[\d._]+/g);
} else if (engine === "gecko") {engineVs = testVs(/gecko\/[\d._]+/g);
} else if (engine === "presto") {engineVs = testVs(/presto\/[\d._]+/g);
} else if (engine === "trident") {engineVs = testVs(/trident\/[\d._]+/g);
}// 载体版本
let supporterVs = "unknow";
if (supporter === "chrome") {supporterVs = testVs(/chrome\/[\d._]+/g);
} else if (supporter === "safari") {supporterVs = testVs(/version\/[\d._]+/g);
} else if (supporter === "firefox") {supporterVs = testVs(/firefox\/[\d._]+/g);
} else if (supporter === "opera") {supporterVs = testVs(/opr\/[\d._]+/g);
} else if (supporter === "iexplore") {supporterVs = testVs(/(msie [\d._]+)|(rv:[\d._]+)/g);
} else if (supporter === "edge") {supporterVs = testVs(/edge\/[\d._]+/g);
}

外壳+外壳版本

let shell = "none";
let shellVs = "unknow";
if (testUa(/micromessenger/g)) {shell = "wechat"; // 微信浏览器shellVs = testVs(/micromessenger\/[\d._]+/g);
} else if (testUa(/qqbrowser/g)) {shell = "qq"; // QQ浏览器shellVs = testVs(/qqbrowser\/[\d._]+/g);
} else if (testUa(/ucbrowser/g)) {shell = "uc"; // UC浏览器shellVs = testVs(/ucbrowser\/[\d._]+/g);
} else if (testUa(/qihu 360se/g)) {shell = "360"; // 360浏览器(无版本)
} else if (testUa(/2345explorer/g)) {shell = "2345"; // 2345浏览器shellVs = testVs(/2345explorer\/[\d._]+/g);
} else if (testUa(/metasr/g)) {shell = "sougou"; // 搜狗浏览器(无版本)
} else if (testUa(/lbbrowser/g)) {shell = "liebao"; // 猎豹浏览器(无版本)
} else if (testUa(/maxthon/g)) {shell = "maxthon"; // 遨游浏览器shellVs = testVs(/maxthon\/[\d._]+/g);
}

终极合体

根据以上的条件判断获得的变量如下,我们可以把它们合并成一个对象输出。这样就可以输出一个清晰的浏览器运行环境,后面想干嘛就干嘛了,多方便。

本文重点探究方案的可行性,没有过多考虑到代码的优化,所以条件判断使用得有些多,如果有什么方法能优化下代码,减少条件判断,可以在下方评论提个建议哟。

  • system:系统
  • systemVs:系统版本
  • platform:平台
  • engine:内核
  • engineVs:内核版本
  • supporter:载体
  • supporterVs:载体版本
  • shell:外壳
  • shellVs:外壳版本
function BrowserType() {const ua = navigator.userAgent.toLowerCase();const testUa = regexp => regexp.test(ua);const testVs = regexp => ua.match(regexp).toString().replace(/[^0-9|_.]/g, "").replace(/_/g, ".");// 接上以上if...else条件判断// ......// 获取到system、systemVs、platform、engine、engineVs、supporter、supporterVs、shell、shellVsreturn Object.assign({engine, // webkit gecko presto tridentengineVs,platform, // desktop mobilesupporter, // chrome safari firefox opera iexplore edgesupporterVs,system, // windows macos linux android iossystemVs}, shell === "none" ? {} : {shell, // wechat qq uc 360 2345 sougou liebao maxthonshellVs});
}

在控制台执行BrowserType(),该有的都出来了,哈哈!源码详情请戳这里,喜欢的可以点个赞支持下,谢谢。

结语

❤️关注+点赞+收藏+评论+转发❤️,原创不易,鼓励笔者创作更好的文章

关注公众号IQ前端,一个专注于CSS/JS开发技巧的前端公众号,更多前端小干货等着你喔

  • 关注后回复关键词免费领取视频教程
  • 关注后添加我微信拉你进技术交流群
  • 欢迎关注IQ前端,更多CSS/JS开发技巧只在公众号推送

详细判断浏览器运行环境相关推荐

  1. js判断浏览器的环境(pc端,移动端,还是微信浏览器)

    window.navigator.userAgent用来区分设备和浏览器 <!DOCTYPE html> <html><head><meta charset= ...

  2. uniapp判断当前运行环境 app h5 微信小程序 百度小程序

    hbuilderX最新版本现在已经支持在代码中获取当前所处环境 仅3.4.10+版本以上才支持,如果您的hbuilderX版本不是这个版本的需要先升级一下版本 hbuilderx下载 选择3.4.11 ...

  3. pycharm详细配置pytest运行环境

    目录 1.设置默认的测试运行器 2.设置运行/调试的配置 3.总结 1.设置默认的测试运行器 打开设置 搜索框输入pytest,进行搜索 查看界面变化 小结 这里只是把测试运行环境设置成了pytest ...

  4. C#判断当前运行环境是否64bit

    C#的应用程序,不强制指定目标平台为x86或x64,那么运行时想判断当前环境到底是不是64bit,可以利用 IntPtr.Size 属性: /// <summary> /// 判定是否运行 ...

  5. uniapp判断当前运行环境 app h5 微信小程序

    仅3.4.10+版本以上才支持,如果您的hbuilderX版本不是这个版本的需要先升级一下版本 hbuilderx下载 选择3.4.11及以上版本 const type = uni.getSystem ...

  6. js判断浏览器环境、内核、载体、外壳、操作系统等

    我们部署在Web服务器上的前端应用,既可以用PC浏览器访问,也可以用手机浏览器访问.项目中很多时候会遇到判断浏览器环境的问题,比如说微信浏览器/APP环境,ios/安卓环境:浏览器是JavaScrip ...

  7. javascript判断浏览器当前运行环境

    认识浏览器 五大国际浏览器品牌:按照全球使用率排序 Google Chrome:Windows.MacOS.Linux.Android.iOS Apple Safari:MacOS.iOS Mozil ...

  8. 国际化和判断当前语言环境

    转过来的资料,国际化和判断当前语言环境! 1.IOS程序名称国际化 1.1 新建一个Single View app模版项目,命名为Localization. 1.2 新建后,可以看到工作目录结构文件如 ...

  9. 浏览器端判断当前设备的运行环境

    浏览器端判断当前设备的运行环境 可判断环境: android iOS weixin Linux windows IE Mac 直接先上代码: let device = function(t) {let ...

最新文章

  1. Nature:运动能力与空间竞争驱动的细菌共存及机制解析
  2. C#中File的使用
  3. xss植入_xss的高级利用
  4. 两个数组结果相减_学点算法(三)——数组归并排序
  5. python 树结构 sqlalchemy_如何从SQLalchemy mod创建json树结构
  6. php 树形结构实例,php:树形结构的算法实例
  7. [CC-CHEFINV]Chef and Swaps
  8. easyrecovery软件如何恢复丢失数据-注册码-序列号-密钥最新绿色下载版
  9. r语言和python语法对比_R语言和Python区别对比,你会选择哪一个?
  10. (2)安装配置开发工具-JsDroid引流脚本混合式开发技术系列教程By飞云脚本学院
  11. 元宇宙专题003 | 如何才能抢先一步,各个省市元宇宙布局抢先看
  12. PHP过滤昵称中emoji表情
  13. mmClassification学习笔记
  14. 为NanoPi M2 自制Debian镜像
  15. win 11 微软 输入法 提示框 提示栏 消失 不见 不显示 找回 显示 可行性 解决方案
  16. LeetCode 661. Image Smoother
  17. 《脑机接口导论》学习笔记 3.记录大脑的信号和刺激大脑
  18. flutter 九宫格菜单_flutter九宫格图片查看器
  19. 鼠标动不了(灯亮着)
  20. 2023 目标,与君共勉

热门文章

  1. 主席树(POJ-2104、HDU-2665)
  2. 用计算机玩反恐精英的男孩,玩CS的男人
  3. 智能硬件,让撩妹更高端
  4. 有源滤波装置在医疗机构中的重要性及应用
  5. 《PC世界》盘点下一个乔布斯 佩奇扎克伯格上榜
  6. 推荐给程序员们的十条编程原则
  7. storybook 编写stories的story基础语法
  8. 计算机软件专业毕业生数量,哪些毕业人数多得吓人的理科专业,你还敢选吗?...
  9. 多孔材料的孔分析-Porous Solid and Powders‘ analysis.
  10. 计算机绘画课程安排,电脑绘画计划及内容安排..doc