【问题标题】:server-side browser detection? node.js服务器端浏览器检测?节点.js
【发布时间】:2011-09-04 00:51:33
【问题描述】:

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

谢谢。

【问题讨论】:

标签: javascript browser node.js browser-detection


【解决方案1】:
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];

这应该适合你。只需将其放入您的响应处理程序中即可。

【讨论】:

  • @float 使用 UA 检测浏览器是一个坏习惯并且不稳定。我建议您尽可能多地查看 CSS @media 属性的委托,以便您可以为移动设备和非移动设备提供不同的 CSS。
  • @Raynos 如果我们计划为使用不同代码库的移动 Web 应用程序提供服务怎么办?也许我们应该合并这两个代码库?
  • 如果用户代理不符合预期的字符串,此脚本将引发异常。例如,ZXing QRCode 阅读器使用“ZXing (Android)”的用户代理字符串,这会导致 /Android ([0-9\.]+)[);]/.exec(ua) 上出现空指针异常[1]。我已经相应地调整了代码。
  • 对于任何寻找设备检测的人,我以前成功使用过这样的东西:npmjs.com/package/express-device
【解决方案2】:

节点的ua-parser 库 (npm install ua-parser) 为浏览器用户代理字符串公开了大量的正则表达式。我强烈推荐它以满足您的需求。

【讨论】:

  • 节点实现在哪里?
  • @MattFletcher 这就是您要找的东西吗? github.com/ua-parser/uap-ref-impl 我想自从我最初发布这个答案以来,它已经在 3 年多的时间里发生了变化。
【解决方案3】:

我使用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 可以获得哪些其他信息,请查看他们的 demo page.

【讨论】:

  • 对不起我上面的评论。 lib没有问题,如果我没有设置X-UA-Compatible元标记,IE会向我发送“假IE 7 ua”。
【解决方案4】:

我想做一个简单的重定向到我的网站的移动版本,所以用户代理足够可靠。我想在服务器端做,所以我没有浪费时间在客户端加载不必要的 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

【讨论】:

    【解决方案5】:

    几个月前我发布了device-detector-js

    它是 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);
    

    看看full API documentation

    【讨论】:

      【解决方案6】:
      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';
      

      【讨论】:

        【解决方案7】:

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

        【讨论】:

          【解决方案8】:

          【讨论】:

            【解决方案9】:

            如果您使用 express,您可以通过以下方式轻松检查 ua:

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

            【讨论】:

              【解决方案10】:

              【讨论】:

                【解决方案11】:

                我对@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]);
                };
                

                【讨论】:

                  【解决方案12】:

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

                  【讨论】:

                    【解决方案13】:

                    如果你想在模板层控制移动,我只是为此编写了一个模块。 https://github.com/Fresheyeball/isMobile-node

                    【讨论】:

                      【解决方案14】:

                      您可能想看看Apache DeviceMap

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

                      【讨论】:

                        【解决方案15】:

                        [这是另一种变体或同化供您考虑。]

                        它更加通用和进一步简化。

                        您可以传递请求或任何具有“标头”属性的对象,也可以是标头属性,您可以选择任何标签来搜索对象或标头或实际用户代理字符串本身的参数。

                        它使用了之前发布的 Mobile and 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() {};
                        

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 2021-03-23
                          • 1970-01-01
                          • 1970-01-01
                          • 2020-01-18
                          • 2021-06-30
                          • 2012-07-08
                          • 2013-08-12
                          • 1970-01-01
                          相关资源
                          最近更新 更多