server-side browser detection? node.js

76,479

Solution 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];

That should work for you. Just put it in your response handler.

Solution 2

The ua-parser library for node (npm install ua-parser) exposes a big set of regexes for browser user-agent strings. I'd strongly recommend it for your needs.

Solution 3

I threw this together using ua-parser-js. I'm sure it can be improved but it's functional.

Install the package:

sudo npm install ua-parser-js

In your routes file require UAParser:

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

Do some stuff with it:

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();
}

and then in your route just call:

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

If you want to see what other information you can get with UAParser check out their demo page.

Solution 4

I wanted to do a simple redirection to a mobile version of my site, so user-agent is reliable enough. I wanted to do it server-side so I didn't waste time loading unnecessary css and js on the client. http://detectmobilebrowsers.com/ had the most robust regex to match. So I threw together some express middleware that will let you do the redirection by just adding two lines of code to your app.

npm install detectmobilebrowsers to install

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

Solution 5

I released device-detector-js a couple months ago.

It's a TypeScript port of Matomo device-detector, a powerful device detection library originally written in PHP.

It can parse any user agent and detect the browser, operating system, device used (desktop, tablet, mobile, tv, cars, console, etc.), brand and model.

Installation

npm install device-detector-js

Example - simple user agent detection:

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

Take a look at the full API documentation.

Share:
76,479
fancy
Author by

fancy

Updated on December 23, 2020

Comments

  • fancy
    fancy over 3 years

    Most implementations i've seen are for browser detection on the client side. I was just wondering if it was possible to do browser detection before sending any resources to the client.

    Thanks.

  • Raynos
    Raynos almost 13 years
    @float using the UA to detect browsers is a bad habit and unstable. I would recommend you look at delegation as much of this to the CSS @media property so you can serve different CSS to mobile and non-mobile devices.
  • fancy
    fancy almost 13 years
    @Raynos what if we are planning to serve a mobile web app that uses a different code base? Maybe we should merge the two code bases instead?
  • Philip Callender
    Philip Callender about 10 years
    This script throws an exception if the user agent doesn't comply with expected strings. For example, the ZXing QRCode reader uses a User Agent string of "ZXing (Android)" and this results in a null pointer exception on /Android ([0-9\.]+)[);]/.exec(ua)[1]. I've adjusted the code accordingly.
  • Matt Fletcher
    Matt Fletcher over 9 years
    Where's the node implementation?
  • S M
    S M over 9 years
    @MattFletcher is this what you're looking for? github.com/ua-parser/uap-ref-impl I guess it's changed in the 3+ years since I originally posted this answer.
  • newshorts
    newshorts about 9 years
    for anyone looking for device detection, i have used something like this with success before: npmjs.com/package/express-device
  • iplus26
    iplus26 over 6 years
    Sorry for my comment above. There's nothing wrong with the lib, instead IE send me the "fake IE 7 ua" if I don't set X-UA-Compatible meta tag.
  • AmerllicA
    AmerllicA about 2 years
    The best answer.