首页 技术 正文
技术 2022年11月20日
0 收藏 954 点赞 2,834 浏览 3743 个字

用户代理检测

前面的文章介绍的是如何检测浏览器对某一功能的支持情况

但是在实践中我们有些时候免不了需要知道用户到底是用的什么浏览器对我们的站点进行访问

这也是统计用户行为的一部分

用户代理检测这种方式就是用于检测用户访问所使用的浏览器的

那么如何进行检测呢?

我之前的文章,讲JS的navigator对象的时候,其中有个 userAgent 属性

这个属性在每次http请求中都会携带在请求头中,这也是我们常说的用户代理字符串

但是要注意的是,这种客户端检测的优先级应该排在 怪癖检测、能力检测之后

作为一种万不得已的手段

为什么呢?因为这和 电子欺骗 有关

所谓电子欺骗,就是指浏览器通过在用户代理字符串中加入错误、误导信息来影响服务器对用户的判断

为什么浏览器要这样做呢?

这就和web早期的发展有关,在早期的发展过程中,用户代理字符串一开始是统一的

但是到了IE4微软希望占据更大的市场,并且希望体现IE的独立性,所以用户代理字符串中就出现了IE自己的标识

这样做使当时的 Netscape(当时最受欢迎的浏览器)很不爽,所以其合作公司通过在服务端检测用户代理字符串,来区分用户

以此来拒绝IE用户的访问

而IE当然不肯善罢甘休,所以就在用户代理字符串中,在不违反标准的情况下添加了混淆信息

其它浏览器厂商纷纷效仿IE

所以检测用户代理字符串来判断浏览器存在一定的风险,准确性也不高

这种方法也就成为了客户端检测的备选方法

和之前一样,这里还是给出一段检测代码

PS:书中检测的只检测到IE11,然而edge的部分并没有,所以这一部分是我自己测试的,有可能会有些问题

用户代理字符串检测函数

// 无需参数
// 返回一个包含浏览器信息的对象
function getClient() {
var engine = {
// 保存浏览器引擎
ie: 0,
gecko: 0,
webkit: 0,
khtml: 0,
opera: 0,
ver: null // 具体版本
}; var browser = {
// 浏览器
ie: 0,
firefox: 0,
safari: 0,
konqueror: 0,// 夸克
opera: 0,
chrome: 0,
ver: null // 浏览器版本
}; var system = {
// PC 端
win: false,
mac: false,
xll: false, // linux
// 移动设备
iphone: false,
ipod: false,
ipad: false,
ios: false,
android: false,
nokiaN: false,
winMobile: false,
// 游戏平台
wii: false,// 任天堂
ps: false
}; var ua = navigator.userAgent;// 获取用户代理字符串 // 浏览器及引擎检测
if(window.opera){// opera 识别
engine.ver = browser.ver = window.opera.version();
engine.opera = browser.opera = parseFloat(engine.ver);
}else if(/AppleWebKit\/(\S+)/.test(ua)){
engine.ver = RegExp["$1"]; // 获取最近一次正则匹配的字符串
engine.webkit = parseFloat(engine.ver);
// 判断谷歌和safari
if(/Edge\/(\S+)/.test(ua)){// Edge 伪装的很好 所以先检测
engine.ver = browser.ver = RegExp["$1"];
engine.webkit = 0;
engine.ie = "Edge";
browser.ie = "Edge";
}else if (/Chrome\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.chrome = parseFloat(browser.ver);
}else if(/Version\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.safari = parseFloat(browser.ver);
}else{
// 近似判断低版本
var safariVersion = 1;
if(engine.webkit<100){
safariVersion = 1;
}else if(engine.webkit<312){
safariVersion = 1.2;
}else if(engine.webkit<412){
safariVersion = 1.3;
}else{
safariVersion = 2;
}
browser.safari = browser.ver = safariVersion;
}
}else if(/KHTML\/(\S+)/.test(ua) || /Konqueror\/([^;]+)/.test(ua)){
// 识别夸克
engine.ver = browser.ver = RegExp["$1"];
engine.khtml = browser.konqueror = parseFloat(engine.ver);
}else if(/rv:([^\)]+)\) Gecko\/\d{8}/.test(ua)){
engine.ver = RegExp["$1"];
engine.gecko = parseFloat(engine.ver); // 识别火狐
if(/Firefox\/(\S+)/.test(ua)){
browser.ver = RegExp["$1"];
browser.firefox = parseFloat(browser.ver);
}
}else if(/MSIE ([^;]+)/.test(ua)||(/Trident\/(\S+)/.test(ua)&&/rv:([^\)]+)\)/.test(ua))){
// 识别IE
engine.ver = browser.ver = RegExp["$1"];
engine.ie = browser.ie = parseFloat(engine.ver);
} // 平台检测
var p = navigator.platform;
system.win = p.indexOf("Win") === 0;
system.mac = p.indexOf("Mac") === 0;
system.xll = (p === "Xll") || (p.indexOf("Linux") === 0); // windows版本
if(system.win){
if(/Win(?:dows) ?([^do]{2})\s?(\d+\.\d+)?/.test(ua)){
if(RegExp["$1"] === "NT"){
switch(RegExp["$2"]){
case "5.0":
system.win = "2000";
break;
case "5.1":
system.win = "XP";
break;
case "6.0":
system.win = "Vista";
break;
case "6.1":
system.win = "7";
break;
default:
system.win = RegExp.$2;
break;
}
}else if(RegExp["$1"] === "9x"){
system.win = "ME";
}else{
system.win = RegExp["$1"];
}
}
} // 移动设备
system.iphone = ua.indexOf("iPhone") > -1;
system.ipod = ua.indexOf("iPod") > -1;
system.ipad = ua.indexOf("iPad") > -1;
system.nokiaN = ua.indexOf("NokiaN") > -1; // windows Phone
if(system.win ==="CE"){
system.winMobile = system.win;
}else if(system.win === "Ph"){
if(/Windows Phone OS (\d+.\d+)/.test(ua)||/Windows Phone (\d+.\d+)/.test(ua)){
system.win = "windowsPhone";
system.winMobile = parseFloat(RegExp["$1"]);
}
} // 检测ios版本
if(system.mac && ua.indexOf("Mobile") > -1){
if(/CPU (?:iPhone)?OS (\d+_\d+)/.test(ua)){
system.ios = parseFloat(RegExp.$1.replace("_","."));
}else{
system.ios = 2; // 具体版本无法测试,默认为2
}
} // 检测安卓版本
if(/Android (\d+\.\d+)/.test(ua)&& !system.winMobile){
system.android = parseFloat(RegExp.$1);
} // 平台检测
system.wii = ua.indexOf("Wii") > -1;
system.ps = /playstation/i.test(ua); return {
engine: engine,
browser: browser,
system: system
};
}
相关推荐
python开发_常用的python模块及安装方法
adodb:我们领导推荐的数据库连接组件bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheeta…
日期:2022-11-24 点赞:878 阅读:9,088
Educational Codeforces Round 11 C. Hard Process 二分
C. Hard Process题目连接:http://www.codeforces.com/contest/660/problem/CDes…
日期:2022-11-24 点赞:807 阅读:5,565
下载Ubuntn 17.04 内核源代码
zengkefu@server1:/usr/src$ uname -aLinux server1 4.10.0-19-generic #21…
日期:2022-11-24 点赞:569 阅读:6,413
可用Active Desktop Calendar V7.86 注册码序列号
可用Active Desktop Calendar V7.86 注册码序列号Name: www.greendown.cn Code: &nb…
日期:2022-11-24 点赞:733 阅读:6,186
Android调用系统相机、自定义相机、处理大图片
Android调用系统相机和自定义相机实例本博文主要是介绍了android上使用相机进行拍照并显示的两种方式,并且由于涉及到要把拍到的照片显…
日期:2022-11-24 点赞:512 阅读:7,822
Struts的使用
一、Struts2的获取  Struts的官方网站为:http://struts.apache.org/  下载完Struts2的jar包,…
日期:2022-11-24 点赞:671 阅读:4,905