纯前端如何识别当前用户访问环境?

2,108 阅读7分钟

怎么识别用户的浏览器

在一个项目中,我们经常会遇到这样的需求,根据用户的浏览器来做一些特殊的处理,比如通过浏览器的UA来判断用户的设备,从而给用户提供不同的体验

但这个需求在我们开发的过程中,往往会遇到一些问题,作为开发者怎么获取用户的UA,怎么判断用户的设备,怎么判断用户的浏览器等等

本文将会带你一步一步的了解这些问题,让你在开发中更加的顺手

UA是什么

UA的全称是User Agent,翻译过来是意思就是用户代理,我们简称为UA,它是一串比较特殊的字符串,用于在每一个HTTP请求中,告知服务器端当前请求的用户所所有的浏览器设备,和渲染引擎,操作系统等信息

在不同的设备中,UA标识也是不同的,通过不同的UA标识,网站可以渲染出不同的排版来而用户提供更好的体验和数据统计等

利用UA渲染不同排版

使用UA判断页面的排版,是一种比较常见的做法,比如在PC端和移动端,我们会有不同的页面排版,这个时候我们就可以通过UA来判断用户的设备,从而给用户提供不同的页面排版、

例如访问百度,当我们使用不同的UA去访问时,会发现页面的排版是不一样的

使用默认UA访问(Chrome for Window)

UA:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36

image.png

指定UA访问(Chrome for Android Mobile)

UA: Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Mobile Safari/537.36

image.png

从上面图中可以看出,当我们使用不同的UA访问时,页面的排版是不一样的,这就是通过UA来判断用户的设备,从而给用户提供不同的页面排版

如何查看UA

查看UA的方法很简单,打开devTools-network,在任意一个请求中的header最底部即可找到一个名为user-agent的请求头,这个就是当前您所向服务器发送的UA

20230313103027

这个是我当前是UA(注意,使用不同浏览器的UA是不一样的,上面的图片我使用的Chrome111版本的)

我们来分析下这一串UA都有些什么数据

user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36

在这之前我们先看看整个UA组成是怎么样的

UA的组成

Mozilla/5.0 (<system-information>) <platform> (<platform-details>) <extensions>
属性属性值说明
<system-information>user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64)当前操作系统
<platform>AppleWebKit/537.36平台
<platform-details>(KHTML, like Gecko)
<extensions>Chrome/111.0.0.0 Safari/537.36浏览器版本,内核

为什么是Mozilla开头

所有的主流的浏览器的UA都采用了Mozilla开头,这还要从一段历史开始说起

在1993年的时候,第一个支持图片格式的浏览器问世了,它叫Mosaic浏览器,由NCSA团队开发的,后来,开发这个浏览器的骨干开始开发了一个新的浏览器,命名为Mozilla(它的任务是干掉Mosaic浏览器),后来由于团队的原因,将该浏览器重命名为Netscape(该浏览器还支持frame特性)

由于不同的浏览器有不同的能力,服务器端出现了UserAgent嗅探技术

一时之间,NetSpace成为了浏览器中最靓的那个浏览器,

作为软件巨头的Microsoft,推出了IE浏览器,希望终结Netscape浏览器

但服务器会嗅探UA啊,如果是Mozilla浏览器才会提供包含Frame页面

这时候IE学会了伪装UA,把UA头携带上Mozilla,告诉服务器我就是Mozilla浏览器,快给我发带有frame的高级页面

之后,MicrosoftWindow中内置了IE浏览器,导致NetScope浏览器一时之间用户量跌入谷底。

又过了一段时间~

新的Mozilla来了,还拥有了Gecko的渲染引擎,后面命名为firefox,并且在UA中携带上firefoxGecko信息

服务器这边这个时候又开始嗅探了,如果UA带有Gecko的,都会赐予用户体验比较好的页面

到了这里,Linux系统这边开发出了一个名为Konqueror的浏览器,采用自家的KHTML渲染引擎。

自称渲染效果和和Gecko的效果一样好!

但服务器还是只会给Gecko提供用户体验比较好的页面

Konqueror开始在UA动手脚了,伪造自己使用的是Gecko浏览器,使用更好的页面

后续新开发的浏览器也开始在UA上进行修改来伪装自己,后来这一操作也成为了标准,所有商业浏览器的UA前缀都是以Mozilla开头

总结:服务器只判断是不是Mozilla,而浏览器都基于Mozilla来扩展

UA的作用

从上面的描述中,我们已经知道了UA的历史,以及通过UA来识别当前用户访问的浏览器

除了用来识别浏览器,UA还有其他的作用,例如:

  • 统计用户浏览器使用情况,如:用户使用的是什么浏览器,什么版本,什么操作系统,什么设备等信息
  • 根据用户设备的UA,提供不同的页面排版,提供更好的用户体验(如识别出是移动端的则返回移动端的页面布局)

当然,我们也是可以修改UA的,但是这样做是不被推荐的,这会导致服务器端无法识别当前用户的设备信息,从而导致无法提供更好的用户体验

如何修改UA

Chrome devTools

首先需要在我们想要修改UA的页面上面打开devTools,然后右上角是一个setting的按钮,点击进去,选择More tools,然后选择Network conditions

20230314123745

之后在User agentuse browser default的勾选取消掉,然后在下面的输入框中指定我们想要的UA即可。

20230314123614

注意该个方法只在当前页面生效,新建浏览器Tab的时候UA会恢复到默认值

如果想要全局生效,可以使用下面的插件

浏览器插件

Chrome插件:User-Agent Switcher for Chrome

Firefox插件:User Agent Switcher

JS怎么获取UA

说了这么多,我们在开发的时候怎么去获取UA,并且推断UA信息

// 获取UA信息
navigator.userAgent
// 输出:Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36
navigator.userAgentData
// 输出:
// {
//     "brands": [
//         {
//             "brand": "Google Chrome",
//             "version": "111"
//         },
//         {
//             "brand": "Not(A:Brand",
//             "version": "8"
//         },
//         {
//             "brand": "Chromium",
//             "version": "111"
//         }
//     ],
//     "mobile": false,
//     "platform": "Windows"
// }

navigator.userAgentData需要在https环境下才能使用,而且仅支持部分浏览器,具体兼容性见下图

20230314221517

SafariFireFox浏览器目前并没有受到支持,所以在平时项目开发中也不建议使用该Api

如果你想要根据用户UA来推断客户端信息,可以使用ua-parser-js这个轮子(库),它可以分析出一个具体信息对象。比上面的navigator.userAgentData还要强大一些。

<script src="https://cdn.jsdelivr.net/npm/ua-parser-js@1.0.34/src/ua-parser.min.js"></script>
<script>
    let parser = new UAParser(navigator.userAgent);
    let parserResults = parser.getResult();
    console.log(parserResults);
</script>
// parserResults
{
    "ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/111.0.0.0 Safari/537.36",
    "browser": {
        "name": "Chrome",
        "version": "111.0.0.0",
        "major": "111"
    },
    "engine": {
        "name": "Blink",
        "version": "111.0.0.0"
    },
    "os": {
        "name": "Windows",
        "version": "10"
    },
    "device": {},
    "cpu": {
        "architecture": "amd64"
    }
}

除了一次性获取全部解析出来的信息,也可以单独调用方法来获取信息,例如只获取当前用户设备信息,用来判断当前用户是否为移动设备访问

let parser = new UAParser(navigator.userAgent);
console.log(parser.getDevice());
// {
//     "vendor": "LG",
//     "model": "Nexus 5",
//     "type": "mobile"
// }

这里只是举其中一个例子,ua-parser-js还提供了其他数据信息获取的方法,点我跳转

参考资料

本文正在参加「金石计划」