likes
comments
collection

User Agent - 识别当前用户的访问环境

作者站长头像
站长
· 阅读数 6

前言

在实际的项目开发中,我们经常会遇到这样的需求,根据用户的浏览器来做一些特殊的处理,比如通过浏览器的 User Agent 来判断用户的设备,从而给用户提供不同的体验。那么 User Agent 是什么呢?开发者怎么获取用户的 User Agent 呢?本文将会一一解答这几个疑惑!

一、User Agent 是什么

User Agent(以下简称 UA),用户代理,它是一串比较特殊的字符串,用于在每一个 HTTP 请求中,告知服务器端当前请求的用户所有的浏览器设备、渲染引擎以及操作系统等信息。

在不同的设备中,UA 标识是不同的,通过不同的 UA 标识,网站可以渲染出不同的排版来为用户提供更好的体验。使用 UA 判断页面的排版,是一种比较常见的做法,比如在 PC 端和移动端,我们会有不同的页面排版,这个时候我们就可以通过 UA 来判断用户的设备,从而给用户提供不同的页面排版。

例如访问百度,当我们用不同的设备去访问时,UA 的值是不一样的:

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

User Agent - 识别当前用户的访问环境

Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1

User Agent - 识别当前用户的访问环境

二、如何查看 UA

  1. 打开 devTools-network,在任意一个请求中的 header 最底部即可找到一个名为 user-agent 的请求头,这个就是当前您所向服务器发送的 UA,(注意,使用不同浏览器的 UA 是不一样的)

User Agent - 识别当前用户的访问环境

  1. 按 F12 打开控制台,输入 navigator.userAgent ,就可以得到关于 UA 的信息

User Agent - 识别当前用户的访问环境

三、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),之后便将该浏览器重命名为 Netscape,由于不同的浏览器有不同的能力,服务器端出现了 UserAgent 嗅探技术,一时之间,NetSpace 成为了浏览器中最靓的那个浏览器。

作为软件巨头的 Microsoft,推出了 IE 浏览器,希望终结 Netscape 浏览器,但服务器会嗅探 UA ,如果是 Mozilla 浏览器才会提供包含 Frame 页面。这时候 IE 学会了伪装 UA,把 UA 头携带上 Mozilla,告诉服务器我就是 Mozilla 浏览器。之后, Microsoft 在 Window 中内置了 IE 浏览器,导致 NetScope 浏览器一时之间用户量跌入谷底。

又过了一段时间,新的 Mozilla 来了,还拥有了 Gecko 的渲染引擎,后面命名为 firefox,并且在 UA 中携带上 firefox 和 Gecko 信息,服务器这边这个时候又开始嗅探了,如果 UA 带有 Gecko 的,都会赐予用户体验比较好的页面。到了这里,Linux 系统这边开发出了一个名为 Konqueror 的浏览器,采用自家的 KHTML 渲染引擎,自称渲染效果和和 Gecko 的效果一样好!但服务器还是只会给 Gecko 提供用户体验比较好的页面,Konqueror 开始在 UA 动手脚了,伪造自己使用的是 Gecko 浏览器,使用更好的页面。后续新开发的浏览器也开始在 UA 上进行修改来伪装自己,后来这一操作也成为了标准,所有商业浏览器的 UA 前缀都是以 Mozilla 开头。

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

五、如何修改UA

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

User Agent - 识别当前用户的访问环境

之后在 User agentuse browser default 勾选取消掉,在下面的输入框中输入想要的UA即可:

User Agent - 识别当前用户的访问环境

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

六、UA 的使用场景

场景1:判断页面是在手机端、PC端还是APP打开

// 是否在PC端
let isPc = ''
if(window.navigator.userAgent.match(/(iPhone|iPod|Android|ios|iOS|iPad|Backerry|WebOS|Symbian|Windows Phone|Phone)/i)) {
    isPc = 'm'; //移动端
} else {
    isPc = 'pc'; //PC端
}

//是否在APP内
let isApp = false
let ua = navigator.userAgent.toLowerCase();
if (ua.match(/isapp/i) == "isapp") {
    isApp = true
}

场景2:判断页面是在手机端,平板端还是PC端打开

var os = function (){
	var ua = navigator.userAgent,
	isWindowsPhone = /(?:Windows Phone)/.test(ua),
	isSymbian = /(?:SymbianOS)/.test(ua) || isWindowsPhone,
	isAndroid = /(?:Android)/.test(ua),
	isFireFox = /(?:Firefox)/.test(ua),
	isChrome = /(?:Chrome|CriOS)/.test(ua),
	isTablet = /(?:iPad|PlayBook)/.test(ua) || (isAndroid && !/(?:Mobile)/.test(ua)) || (isFireFox && /(?:Tablet)/.test(ua)),
	isPhone = /(?:iPhone)/.test(ua) && !isTablet,
	isPc = !isPhone && !isAndroid && !isSymbian;
	return {
		isTablet: isTablet,
		isPhone: isPhone,
		isAndroid: isAndroid,
		isPc: isPc
	};	
}();
 
if (os.isAndroid || os.isPhone) {   
   alert("手机" );
} else if (os.isTablet) {
    alert("平板" );
} else if (os.isPc) {
    alert("电脑" );
}

场景3:获取操作系统类型,判断是Android或者IOS

/**
     * 获取操作系统类型,
     * 0 Android
     * 1 iOS
     */
    function getOSType() {
        if (/(Android)/i.test(navigator.userAgent)) {
            return 0;
        } else if (/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)) {
            return 1;
        } else {
            return 2;
        }
    }

场景4:判断当前环境是否是微信环境

function is_weixin(){
      var ua = navigator.userAgent.toLowerCase();
      if(ua.match(/MicroMessenger/i)=="micromessenger") {
           return true;
     } else {
            return false;
      }
}