服务器端浏览器检测

我见过的大多数实现都是用于客户端的浏览器检测。我只是想知道是否有可能在向客户端发送任何资源之前进行浏览器检测。

谢谢。

80408 次浏览

大多数浏览器都提供一个名为“ User-Agent”的 HTTP 请求头,这与客户端的 Navator.userAgent 属性相同。

var ua = request.headers['user-agent'],
$ = {};


if (/mobile/i.test(ua))
$.Mobile = true;


if (/like Mac OS X/.test(ua)) {
$.iOS = /CPU( iPhone)? OS ([0-9\._]+) like Mac OS X/.exec(ua)[2].replace(/_/g, '.');
$.iPhone = /iPhone/.test(ua);
$.iPad = /iPad/.test(ua);
}


if (/Android/.test(ua))
$.Android = /Android ([0-9\.]+)[\);]/.exec(ua)[1];


if (/webOS\//.test(ua))
$.webOS = /webOS\/([0-9\.]+)[\);]/.exec(ua)[1];


if (/(Intel|PPC) Mac OS X/.test(ua))
$.Mac = /(Intel|PPC) Mac OS X ?([0-9\._]*)[\)\;]/.exec(ua)[2].replace(/_/g, '.') || true;


if (/Windows NT/.test(ua))
$.Windows = /Windows NT ([0-9\._]+)[\);]/.exec(ua)[1];

这对你来说应该可以,只要把它放到你的反应处理程序里。

节点的 解析器库(npm install ua-parser)为浏览器用户代理字符串公开了一大组正则表达式。我强烈建议你用它来满足你的需求。

如果你使用的是 Express,你可以很容易地用下面的方法来检查 ua:

app.get('/ua', function(req, res){
res.send('user ' + req.headers['user-agent']);
});

我想做一个简单的重定向到我的网站的移动版本,所以用户代理是足够可靠的。我想在服务器端做这件事,这样我就不会浪费时间在客户端加载不必要的 css 和 js。http://detectmobilebrowsers.com/拥有最健壮的正则表达式来匹配。因此,我将一些快速中间件组合在一起,通过向应用程序中添加两行代码,就可以实现重定向。

安装 npm install detectmobilebrowsers

express = require 'express'
mobile  = require 'detectmobilebrowsers'


app = express()
app.configure () ->
app.use mobile.redirect 'http://m.domain.com'
app.get '/', (req, res) ->
res.send 'Not on Mobile'
app.listen 3000

如果你想在模板层控制手机,我刚刚为此编写了一个模块。 Https://github.com/fresheyeball/ismobile-node

ua = request.headers['user-agent'];
if( /firefox/i.test(ua) )
browser = 'firefox';
else if( /chrome/i.test(ua) )
browser = 'chrome';
else if( /safari/i.test(ua) )
browser = 'safari';
else if( /msie/i.test(ua) )
browser = 'msie';
else
browser = 'unknown';

我用 Ua-parser-js把它们拼凑在一起。我确信它们可以被改进,但是它们是实用的。

安装软件包:

sudo npm install ua-parser-js

在路线文件中需要 UAParser:

var UAParser = require('ua-parser-js');

用它做一些事情:

function ensureLatestBrowser(req, res, next) {
var parser = new UAParser();
var ua = req.headers['user-agent'];
var browserName = parser.setUA(ua).getBrowser().name;
var fullBrowserVersion = parser.setUA(ua).getBrowser().version;
var browserVersion = fullBrowserVersion.split(".",1).toString();
var browserVersionNumber = Number(browserVersion);


if (browserName == 'IE' && browserVersion <= 9)
res.redirect('/update/');
else if (browserName == 'Firefox' && browserVersion <= 24)
res.redirect('/update/');
else if (browserName == 'Chrome' && browserVersion <= 29)
res.redirect('/update/');
else if (browserName == 'Canary' && browserVersion <= 32)
res.redirect('/update/');
else if (browserName == 'Safari' && browserVersion <= 5)
res.redirect('/update/');
else if (browserName == 'Opera' && browserVersion <= 16)
res.redirect('/update/');
else
return next();
}

然后在路上给我打电话:

app.all(/^(?!(\/update)).*$/, ensureLatestBrowser);

如果你想看看还有什么其他信息可以用 UAParser 查看他们的 演示页面。

我改进了一点@duck5auce 的代码,使其真正有用,并支持 IE 10-12(Edge)。

var getDevice = function(ua) {
var $ = {active: false, subactive: false};


if (/mobile/i.test(ua)) {
$.active = 'mobile';
$.Mobile = true;
}


if (/like Mac OS X/.test(ua)) {
$.active = 'iOS';
$.iOS = /CPU( iPhone)? OS ([0-9\._]+) like Mac OS X/.exec(ua)[2].replace(/_/g, '.');
if (/like Mac OS X/.test(ua)) {
$.subactive = 'iPhone';
$.iPhone = /iPhone/.test(ua);
}
if (/like Mac OS X/.test(ua)) {
$.subactive = 'iPad';
$.iPad = /iPad/.test(ua);
}
}


if (/Android/.test(ua)) {
$.active = 'Android';
$.Android = /Android ([0-9\.]+)[\);]/.exec(ua)[1];
}


if (/webOS\//.test(ua)) {
$.active = 'webOS';
$.webOS = /webOS\/([0-9\.]+)[\);]/.exec(ua)[1];
}


if (/(Intel|PPC) Mac OS X/.test(ua)) {
$.active = 'Safari';
$.Safari = /(Intel|PPC) Mac OS X ?([0-9\._]*)[\)\;]/.exec(ua)[2].replace(/_/g, '.') || true;
}


if (/Windows NT/.test(ua)) {
$.active = 'IE';
$.IE = /Windows NT ([0-9\._]+)[\);]/.exec(ua)[1];
}
if (/MSIE/.test(ua)) {
$.active = 'IE';
$.IE = /MSIE ([0-9]+[\.0-9]*)/.exec(ua)[1];
}
if (/Trident/.test(ua)) {
$.active = 'IE';
$.IE = /Trident\/.*rv:([0-9]+[\.0-9]*)/.exec(ua)[1];
}
if (/Edge\/\d+/.test(ua)) {
$.active = 'IE Edge';
$.IE = /Edge\/(\d+)/.exec(ua)[1];
}


return $.active + ' ' + $[$.active] + ($.subactive && ' ' + $.subactive + ' ' + $[$.subactive]);
};

你可能想看看 Apache DeviceMap

现在开箱即用的 JavaScript 库更多的是在客户端,但是很多在 Node.JS 或 Angular 上也会以类似的方式工作。与简单的 UA 字符串模式匹配不同,DeviceMap 在其基于 W3C 标准的设备描述存储库(Device Description Repository,DDR)中提供了大量的设备和设备系列。

几个月前我发布了 器件检测器

它是 Matomo 设备检测器的一个 TypeScript 端口,这是一个最初用 PHP 编写的强大的设备检测库。

它可以解析任何用户代理,并检测浏览器、操作系统、使用的设备(桌面、平板电脑、手机、电视、汽车、控制台等)、品牌和型号。

安装

npm install device-detector-js

示例 -简单用户代理检测:

const DeviceDetector = require("device-detector-js");


const deviceDetector = new DeviceDetector();
const userAgent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36";
const device = deviceDetector.parse(userAgent);


console.log(device);

看看 完整的 API 文档

强大的 npm 用户代理。 Useragent 允许您使用手工调优的专用正则表达式进行浏览器匹配,从而高精度地解析用户代理字符串。需要这个数据库来确保每个浏览器都被正确解析,因为每个浏览器供应商都实现了自己的用户代理模式。这就是为什么普通的用户代理解析器会出现重大问题,因为它们很可能解析出错误的浏览器名称,或者将呈现引擎版本与浏览器的实际版本混淆。

[这里有另一个变化或同化供你考虑。]

它更通用和进一步简化。

您可以传递 Request 或任何具有“ headers”属性的对象,或者它可以是 headers 属性,您可以选择任何标签来搜索对象上的参数、 Header 或实际的用户代理字符串本身。

它使用了之前发布的 Mobile 和 Table Checking Regex,并简单地返回结果,但是通过首先神圣化输入,就可以插入各种东西。

您甚至可以覆盖作为参数可以任意传递的默认正则表达式 还可以有另一种方法来默认从请求到全局存储的用户代理(如果在范围内等)。

mobTabCheck: function( ua, lbl, rgx ) {  /* mobile tablet check; UserAgent or request, or any object with optional search label  */
if( ua === und ) return false;
if( ua !== und && ua.constructor !== String ) {
if( lbl === und ) lbl = 'user-agent';
if( ua.headers !== und ) ua = ua.headers[ lbl ];
else ua = ua[ lbl ];
}
if( rgx === und ) rgx = /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/;
if( rgx.constructor === String ) rgx = new RegExp( rgx );
return rgx.test( ua );
}

这个正则表达式是从这里来的。 Https://gist.github.com/dalethedeveloper/1503252/931cc8b613aaa930ef92a4027916e6687d07feac

98% 解决方案。我不知道它是否像我的函数标题暗示的那样检查平板电脑。

实际上这个函数的标题(和一些参数)应该重命名? ... serachObjectForLabelThatMatchesThisRegex

除了所有的默认值使它成为一个单独的参数。

另外,我将函数集保留为键的值,您可以按照自己喜欢的方式存储它,比如... ... 只要答应我,如果您使用它,不要使用 var 或 const。

let mobTabCheck = function() {};

我有一个类似的需求,我遇到了这个节点包称为 检测-浏览器

const { detect } = require('detect-browser');
const browser = detect();


if (browser) {
console.log(browser.name);
console.log(browser.version);
console.log(browser.os);
}

或者,如果您想根据特定的浏览器执行任何操作,您也可以使用下面这样的开关案例

const { detect } = require('detect-browser');
const browser = detect();


// handle the case where we don't detect the browser
switch (browser && browser.name) {
case 'chrome':
case 'firefox':
console.log('supported');
break;


case 'edge':
console.log('kinda ok');
break;


default:
console.log('not supported');
}