用户代理检测

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

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

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

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

那么如何进行检测呢?

我之前的文章,讲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
};
}

Javascript高级编程学习笔记(34)—— 客户端检测(3)用户代理检测的更多相关文章

  1. Javascript高级编程学习笔记(32)—— 客户端检测(1)能力检测

    能力检测 浏览器厂商虽然在实现公共接口方面投入了大量的精力 但是每种浏览器仍旧存在许多差异 为了让网页能跨浏览器的运行,对浏览器差异做的兼容处理自然无法避免 其中最常用的也就是我们现在所说的能力检测 ...

  2. Javascript高级编程学习笔记(33)—— 客户端检测(2)怪癖检测

    怪癖检测 和能力检测类似,但其目标不同 能力检测的目的是判断浏览器支不支持某种能力 而怪癖检测的目的是判断浏览器是否存在某些缺陷 这种时候需要我们执行一段代码来判断浏览器是否有这样的缺陷 或者说是怪癖 ...

  3. Javascript高级编程学习笔记(98)—— WebGL(4) WebGL上下文(2)

    错误 Javascript与WebGL之间的一个最大区别在于,WebGL的操作一般不会抛出错误 如果希望获取WebGL的错误信息,那么就需要手动调用  gl.getError() 方法 该方法会返回以 ...

  4. Javascript高级编程学习笔记(97)—— WebGL(3) WebGL上下文(1)

    WebGL上下文 在支持WebGL的浏览器中,WebGL的名字为 "experimental-webgl",这是由于 webgl 的规范仍未制定完成 制定完成后名字就会改为简单的 ...

  5. Javascript高级编程学习笔记(75)—— 表单(3)表单字段

    表单字段 表单作为web应用中不可或缺的一部分,当然也是可以使用原生的 DOM 元素来访问的 除了标准的访问方式之外,每个表单都拥有一个 elements 属性,该属性保存着该表单所有 表单元素 的集 ...

  6. Javascript高级编程学习笔记(64)—— 事件(8)键盘与文本事件

    键盘与文本事件 用户在使用键盘时会触发键盘事件 “DOM2级事件”最初规定了键盘事件,但是最后在定稿时又删除了相应内容 所以键盘事件被放入了DOM3级事件的规范中 总的来说有三个键盘事件: keydo ...

  7. Javascript高级编程学习笔记(53)—— DOM2和DOM3(5)遍历

    遍历 “DOM2级遍历和范围” 定义了两个用于辅助完成顺序遍历的DOM结构类型 NodeIterator 和 TreeWalk 上述两种类型可以基于给定起点的DOM结构执行深度优先的遍历操作 对于检测 ...

  8. Javascript高级编程学习笔记(49)—— DOM2和DOM3(1)DOM变化

    DOM变化 我们知道DOM有许多的版本,其中DOM0和DOM2这两个级别以对事件的纳入标准而为人所知 但是呢,这里不讲事件,在后面会有专门和事件有关的部分作为详细讲解 这里就只讲一下DOM2和DOM3 ...

  9. Javascript高级编程学习笔记(31)—— BOM(5)screen、history对象

    screen对象 screen对象应该是BOM对象中最不常用的对象了 其主要用于提供客户端的显示能力信息 包括浏览器外部显示的信息,和像素的宽高等 这个对象的主要用于检测客户端能力,一般不会影响功能 ...

随机推荐

  1. MUI 添加自定义图标(注意点)

    参考: https://blog.csdn.net/qq_39759115/article/details/79436606 注意: 1. 将这个原来的逗号改成分号 2. 这些图标的名字都可以改名字

  2. position在IE下的问题

    盒子设置position:absolute;后,子盒子的浮动可以不做清除浮动处理,同样,使用fixed,子盒子也不需要做清除浮动的处理 在IE7下(据说IE6也不行),盒子设置overflow:hid ...

  3. 输入ip和端口号python脚本py文件

    1.利用.py文件进行打开URL,编辑以下文件代码保存文件为login.py: # _*_ coding: cp936 _*__all_ = ['ip','port','root_id']ip='10 ...

  4. 递归,re,time,random

    递归函数 1.在函数中调用自己 2.超过递归的最大深度报错,递归的最大深度:998大概 3.递归的缺点:占内存 4.优点:代码简单 import sys sys.setrecursionlimit(2 ...

  5. node.js生成二维码

    var http = require('http'); var qs = require('querystring'); var qrImg = require('qr-image'); var se ...

  6. CSS定位网页中的元素

    relative相对定位 偏移设置:left.right.top.bottom 值单位:px 元素的规律: 相对定位元素的规律 设置相对定位的盒子会相对它原来的位置通过指定偏移,到达新的位置. 设置相 ...

  7. python爬虫知识脉络

  8. 博客1--tensorflow的图像基本处理操作

    话不多,具体内容在开源中国里我的博客:https://my.oschina.net/u/3770644 代码: #!/usr/bin/env python# -*- coding:utf-8 -*-# ...

  9. 最小化webpack项目

    先把代码贴出来,以后慢慢加说明 参考资料:入门 Webpack,看这篇就够了 / webpack 搭建自动打开,刷新浏览器 一.功能代码1.index.html <!DOCTYPE html&g ...

  10. 刷机魅蓝note2

    直接上了. 情况: 魅蓝note2 公共版  忘记flyme 密码,手机号也换了,,找不回了..只能刷了.网上说就算刷了也不行,还是要输入flyme 密码 1. 直接刷官方的zip 包,不行,仍然要输 ...