UNPKG

12.3 kBMarkdownView Raw
1# useragent - high performance user agent parser for Node.js
2
3Useragent originated as port of [browserscope.org][browserscope]'s user agent
4parser project also known as ua-parser. Useragent allows you to parse user agent
5string with high accuracy by using hand tuned dedicated regular expressions for
6browser matching. This database is needed to ensure that every browser is
7correctly parsed as every browser vendor implements it's own user agent schema.
8This is why regular user agent parsers have major issues because they will
9most likely parse out the wrong browser name or confuse the render engine version
10with the actual version of the browser.
11
12---
13
14### Build status [![BuildStatus](https://secure.travis-ci.org/3rd-Eden/useragent.png?branch=master)](http://travis-ci.org/3rd-Eden/useragent)
15
16---
17
18### High performance
19
20The module has been developed with a benchmark driven approach. It has a
21pre-compiled library that contains all the Regular Expressions and uses deferred
22or on demand parsing for Operating System and device information. All this
23engineering effort has been worth it as [this benchmark shows][benchmark]:
24
25```
26Starting the benchmark, parsing 62 useragent strings per run
27
28Executed benchmark against node module: "useragent"
29Count (61), Cycles (5), Elapsed (5.559), Hz (1141.3739447904327)
30
31Executed benchmark against node module: "useragent_parser"
32Count (29), Cycles (3), Elapsed (5.448), Hz (545.6817291171243)
33
34Executed benchmark against node module: "useragent-parser"
35Count (16), Cycles (4), Elapsed (5.48), Hz (304.5373431830105)
36
37Executed benchmark against node module: "ua-parser"
38Count (54), Cycles (3), Elapsed (5.512), Hz (1018.7561434659247)
39
40Module: "useragent" is the user agent fastest parser.
41```
42
43---
44
45### Installation
46
47Installation is done using the Node Package Manager (NPM). If you don't have
48NPM installed on your system you can download it from
49[npmjs.org][npm]
50
51```
52npm install useragent --save
53```
54
55The `--save` flag tells NPM to automatically add it to your `package.json` file.
56
57---
58
59### API
60
61
62Include the `useragent` parser in you node.js application:
63
64```js
65var useragent = require('useragent');
66```
67
68The `useragent` library allows you do use the automatically installed RegExp
69library or you can fetch it live from the remote servers. So if you are
70paranoid and always want your RegExp library to be up to date to match with
71agent the widest range of `useragent` strings you can do:
72
73```js
74var useragent = require('useragent');
75useragent(true);
76```
77
78This will async load the database from the server and compile it to a proper
79JavaScript supported format. If it fails to compile or load it from the remote
80location it will just fall back silently to the shipped version. If you want to
81use this feature you need to add `yamlparser` and `request` to your package.json
82
83```
84npm install yamlparser --save
85npm install request --save
86```
87
88#### useragent.parse(useragent string[, js useragent]);
89
90This is the actual user agent parser, this is where all the magic is happening.
91The function accepts 2 arguments, both should be a `string`. The first argument
92should the user agent string that is known on the server from the
93`req.headers.useragent` header. The other argument is optional and should be
94the user agent string that you see in the browser, this can be send from the
95browser using a xhr request or something like this. This allows you detect if
96the user is browsing the web using the `Chrome Frame` extension.
97
98The parser returns a Agent instance, this allows you to output user agent
99information in different predefined formats. See the Agent section for more
100information.
101
102```js
103var agent = useragent.parse(req.headers['user-agent']);
104
105// example for parsing both the useragent header and a optional js useragent
106var agent2 = useragent.parse(req.headers['user-agent'], req.query.jsuseragent);
107```
108
109The parse method returns a `Agent` instance which contains all details about the
110user agent. See the Agent section of the API documentation for the available
111methods.
112
113#### useragent.lookup(useragent string[, js useragent]);
114
115This provides the same functionality as above, but it caches the user agent
116string and it's parsed result in memory to provide faster lookups in the
117future. This can be handy if you expect to parse a lot of user agent strings.
118
119It uses the same arguments as the `useragent.parse` method and returns exactly
120the same result, but it's just cached.
121
122```js
123var agent = useragent.lookup(req.headers['user-agent']);
124```
125
126And this is a serious performance improvement as shown in this benchmark:
127
128```
129Executed benchmark against method: "useragent.parse"
130Count (49), Cycles (3), Elapsed (5.534), Hz (947.6844321931629)
131
132Executed benchmark against method: "useragent.lookup"
133Count (11758), Cycles (3), Elapsed (5.395), Hz (229352.03831239208)
134```
135
136#### useragent.fromJSON(obj);
137
138Transforms the JSON representation of a `Agent` instance back in to a working
139`Agent` instance
140
141```js
142var agent = useragent.parse(req.headers['user-agent'])
143 , another = useragent.fromJSON(JSON.stringify(agent));
144
145console.log(agent == another);
146```
147
148#### useragent.is(useragent string).browsername;
149
150This api provides you with a quick and dirty browser lookup. The underlying
151code is usually found on client side scripts so it's not the same quality as
152our `useragent.parse` method but it might be needed for legacy reasons.
153
154`useragent.is` returns a object with potential matched browser names
155
156```js
157useragent.is(req.headers['user-agent']).firefox // true
158useragent.is(req.headers['user-agent']).safari // false
159var ua = useragent.is(req.headers['user-agent'])
160
161// the object
162{
163 version: '3'
164 webkit: false
165 opera: false
166 ie: false
167 chrome: false
168 safari: false
169 mobile_safari: false
170 firefox: true
171 mozilla: true
172 android: false
173}
174```
175
176---
177
178### Agents, OperatingSystem and Device instances
179
180Most of the methods mentioned above return a Agent instance. The Agent exposes
181the parsed out information from the user agent strings. This allows us to
182extend the agent with more methods that do not necessarily need to be in the
183core agent instance, allowing us to expose a plugin interface for third party
184developers and at the same time create a uniform interface for all versioning.
185
186The Agent has the following property
187
188- `family` The browser family, or browser name, it defaults to Other.
189- `major` The major version number of the family, it defaults to 0.
190- `minor` The minor version number of the family, it defaults to 0.
191- `patch` The patch version number of the family, it defaults to 0.
192
193In addition to the properties mentioned above, it also has 2 special properties,
194which are:
195
196- `os` OperatingSystem instance
197- `device` Device instance
198
199When you access those 2 properties the agent will do on demand parsing of the
200Operating System or/and Device information.
201
202The OperatingSystem has the same properties as the Agent, for the Device we
203don't have any versioning information available, so only the `family` property is
204set there. If we cannot find the family, they will default to `Other`.
205
206The following methods are available:
207
208#### Agent.toAgent();
209
210Returns the family and version number concatinated in a nice human readable
211string.
212
213```js
214var agent = useragent.parse(req.headers['user-agent']);
215agent.toAgent(); // 'Chrome 15.0.874'
216```
217
218#### Agent.toString();
219
220Returns the results of the `Agent.toAgent()` but also adds the parsed operating
221system to the string in a human readable format.
222
223```js
224var agent = useragent.parse(req.headers['user-agent']);
225agent.toString(); // 'Chrome 15.0.874 / Mac OS X 10.8.1'
226
227// as it's a to string method you can also concat it with another string
228'your useragent is ' + agent;
229// 'your useragent is Chrome 15.0.874 / Mac OS X 10.8.1'
230```
231#### Agent.toVersion();
232
233Returns the version of the browser in a human readable string.
234
235```js
236var agent = useragent.parse(req.headers['user-agent']);
237agent.toVersion(); // '15.0.874'
238```
239
240#### Agent.toJSON();
241
242Generates a JSON representation of the Agent. By using the `toJSON` method we
243automatically allow it to be stringified when supplying as to the
244`JSON.stringify` method.
245
246```js
247var agent = useragent.parse(req.headers['user-agent']);
248agent.toJSON(); // returns an object
249
250JSON.stringify(agent);
251```
252
253#### OperatingSystem.toString();
254
255Generates a stringified version of operating system;
256
257```js
258var agent = useragent.parse(req.headers['user-agent']);
259agent.os.toString(); // 'Mac OSX 10.8.1'
260```
261
262#### OperatingSystem.toVersion();
263
264Generates a stringified version of operating system's version;
265
266```js
267var agent = useragent.parse(req.headers['user-agent']);
268agent.os.toVersion(); // '10.8.1'
269```
270
271#### OperatingSystem.toJSON();
272
273Generates a JSON representation of the OperatingSystem. By using the `toJSON`
274method we automatically allow it to be stringified when supplying as to the
275`JSON.stringify` method.
276
277```js
278var agent = useragent.parse(req.headers['user-agent']);
279agent.os.toJSON(); // returns an object
280
281JSON.stringify(agent.os);
282```
283
284#### Device.toString();
285
286Generates a stringified version of device;
287
288```js
289var agent = useragent.parse(req.headers['user-agent']);
290agent.device.toString(); // 'Asus A100'
291```
292
293#### Device.toVersion();
294
295Generates a stringified version of device's version;
296
297```js
298var agent = useragent.parse(req.headers['user-agent']);
299agent.device.toVersion(); // '' , no version found but could also be '0.0.0'
300```
301
302#### Device.toJSON();
303
304Generates a JSON representation of the Device. By using the `toJSON` method we
305automatically allow it to be stringified when supplying as to the
306`JSON.stringify` method.
307
308```js
309var agent = useragent.parse(req.headers['user-agent']);
310agent.device.toJSON(); // returns an object
311
312JSON.stringify(agent.device);
313```
314
315### Adding more features to the useragent
316
317As I wanted to keep the core of the user agent parser as clean and fast as
318possible I decided to move some of the initially planned features to a new
319`plugin` file.
320
321These extensions to the Agent prototype can be loaded by requiring the
322`useragent/features` file:
323
324```js
325var useragent = require('useragent');
326require('useragent/features');
327```
328
329The initial release introduces 1 new method, satisfies, which allows you to see
330if the version number of the browser satisfies a certain range. It uses the
331semver library to do all the range calculations but here is a small summary of
332the supported range styles:
333
334* `>1.2.3` Greater than a specific version.
335* `<1.2.3` Less than.
336* `1.2.3 - 2.3.4` := `>=1.2.3 <=2.3.4`.
337* `~1.2.3` := `>=1.2.3 <1.3.0`.
338* `~1.2` := `>=1.2.0 <2.0.0`.
339* `~1` := `>=1.0.0 <2.0.0`.
340* `1.2.x` := `>=1.2.0 <1.3.0`.
341* `1.x` := `>=1.0.0 <2.0.0`.
342
343As it requires the `semver` module to function you need to install it
344seperately:
345
346```
347npm install semver --save
348```
349
350#### Agent.satisfies('range style here');
351
352Check if the agent matches the supplied range.
353
354```js
355var agent = useragent.parse(req.headers['user-agent']);
356agent.satisfies('15.x || >=19.5.0 || 25.0.0 - 17.2.3'); // true
357agent.satisfies('>16.12.0'); // false
358```
359---
360
361### Migrations
362
363For small changes between version please review the [changelog][changelog].
364
365#### Upgrading from 1.10 to 2.0.0
366
367- `useragent.fromAgent` has been removed.
368- `agent.toJSON` now returns an Object, use `JSON.stringify(agent)` for the old
369 behaviour.
370- `agent.os` is now an `OperatingSystem` instance with version numbers. If you
371 still a string only representation do `agent.os.toString()`.
372- `semver` has been removed from the dependencies, so if you are using the
373 `require('useragent/features')` you need to add it to your own dependencies
374
375#### Upgrading from 0.1.2 to 1.0.0
376
377- `useragent.browser(ua)` has been renamed to `useragent.is(ua)`.
378- `useragent.parser(ua, jsua)` has been renamed to `useragent.parse(ua, jsua)`.
379- `result.pretty()` has been renamed to `result.toAgent()`.
380- `result.V1` has been renamed to `result.major`.
381- `result.V2` has been renamed to `result.minor`.
382- `result.V3` has been renamed to `result.patch`.
383- `result.prettyOS()` has been removed.
384- `result.match` has been removed.
385
386---
387
388### License
389
390MIT
391
392[browserscope]: http://www.browserscope.org/
393[benchmark]: /3rd-Eden/useragent/blob/master/benchmark/run.js
394[changelog]: /3rd-Eden/useragent/blob/master/CHANGELOG.md
395[npm]: http://npmjs.org