Tutorial #26
Browser Information Intermediate   2013-11-25


In many server applications we want to customize the content we send to a browser. We might want to respond in the Language that the user speaks. We want to adjust the page layout if they are using a phone versus a desktop and we might need to adjust the page content if their browser does not support a particular feature..

There are three ways to do this:

1: We can extract some, but not all the information from the HTTP Request Headers that are sent by your browser every time it requests a web page.

2: We can derive some information by running JavaScript code on the client's browser and passing back that data with Ajax.

3: We can ask the user - they can specify their language, time zone, location, etc in some way, such as web cookies or preferences that are stored on the server.

The first of these is the easiest and involves only simple code on the server end. This tutorial shows you what you can, and cannot, derive from this approach.

Demo 1 screenshot for this tutorial

Step by Step

Take a look at the demo. The information listed there reflects what the server can determine based solely on the HTTP request headers.

The first block of text shows the current URL (which we already know because that is the page we are looking at!), the two parameters passed with that URL and the Request Method, typically GET or POST. The parameters are very useful for directing the server action invoked by this request.

Image 1 for this tutorial

The last line is the Referrer. If the user typed the URL into their browser directly then this is blank, but if they clicked on a link on another page, the URL of that page is listed here. It tells you where the user was before they came here, which can be very useful.

The second block show the results of several utility methods that simply extract the different parts of the URL. Useful, but they don't tell us anything we don't already know.

The next set of lines are typically the most useful.

Image 2 for this tutorial

The IP address shows the numeric internet address of the client's computer. Not that informative by itself so I have linked this to an IP address lookup service that may be able show you where that computer is located. Even if that is not possible, you may be able to use the address to identify that user to some extent. But be aware that multiple users may appear to come from the same IP address.

Probably the most useful line is the User Agent which can tell us which Browser is being used, its Version and the Platform on which it is being run (Mac, Windows, iPhone, Android, etc.).

The string can be confusing. This example refers to Mozilla, Chrome and Safari... so which is it?

Rather than trying to parse it out, I'm using the UserAgent ruby gem to handle it for me.That is what produces the next three lines that identify the browser as Google Chrome version 31 running on a Mac. It doesn't get everything though, the UserAgent string indicates that the Mac is running Mac OS X 10.7.5.

Some browsers allow you to set the User Agent to something other than it's true value. This is useful for testing but can be misused to spoof web servers. I'm not sure why you want to do this, but be aware that it is easy for a user to do.

If you have any cookies set then you can view their values in the next section. Finally, the Accept and Accept Encoding lines tell the server what types of content it can handle and how that content can be encoded in a compressed format, such as gzip.

Missing from the Request object in the Rack ruby gem, which is used by Sinatra to handle this function), is Accept Language. This is a standard way for a browser to tell the server which language the user prefers to receive content. This is a big oversight in Rack as it is very useful. Hopefully it will be added soon (I submitted a pull request with the code to Rack in Nov 2013).

Understanding the Code

For simplicity's sake, I wrote the code to extract and display all these values as an ERB template. In practice you would handle the values in your controller and branch as needed.

The code block consists of a table with key/value pairs on each line. The request object is built into Sinatra (it actually comes from Rack which Sinatra uses.

If you are not familar with ERB templates, strings like <%= request.ip %> insert the value of request.ip into the HTML that is sent to the browser.

Parsing the User Agent string is done with the UserAgent gem. So you need to add gem 'user_agent' to your server's Gemfile and run bundle install.

This approach misses some very important pieces of information about the users and their environments. I've mentioned the Language preference. We don't know their Time Zone or, to any accuracy, their Location. JavaScript can help with some of this (see the Geolocation tutorial for one piece of that puzzle.
But if your application tracks User Accounts then the most direct approach is to ask the user to enter the information in their profile.

Code for this Tutorial

Share this tutorial

Comment on this Tutorial

comments powered by Disqus