Before talking about detection of mobile devices and
services on the server, we need to go back a bit and consider an old
friend: the HyperText Transfer Protocol, also known as HTTP. Knowing a
bit about its internals will help us determine what we can do in terms of
mobile web development.
Note:
There are no special server requirements for mobile websites; you
can just use the same Apache, Internet Information Server (IIS), or
other server you are currently using for desktop websites.
1. HTTP
HTTP is a protocol originally defined in 1991 for document
transportation over TCP/IP networks. It has two main versions: 1.0 and
1.1 (the last and current version of the protocol, defined in 1996).
This same protocol is the one that we need to use from the server side
in mobile web development.
Actually, the last sentence isn’t strictly true if we consider WAP
1.1, where the device communicates with the WAP gateway and the WAP
gateway is the one connecting to our server via HTTP. A similar approach
is used in proxied browsers, like Opera Mini and Bolt (see Figure 1). However, from
the server’s point of view the requests coming in will always be HTTP
requests.
1.1. The request
An HTTP request involves a client (the browser) sending a
request to a server using its IP address (previously converted from a
domain name). That request has a header and an optional body. The body
is generally sent when we are doing a POST request. The most common request type
is a GET, requesting a document or
a file from the server.
Note:
Verizon uses an Optimized View enhancement (a transcoder) for
mobile websites that are not on one of the mobile addressing
standards (.mobi, wap., m., etc.). If you want to avoid
transcoding of your site you can make an opt-out request at http://vzwdevelopers.com/aims/public/OptimizedViewOptout.jsp.
The server responds with a response status code (hopefully not
the famous 404), a header, and an optional (but generally sent) body.
The body is the requested file.
Why are we taking this two-minute networking class? Because it
illustrates many of the techniques we will use in server-side
detection.
1.2. The request header
The request header has many attributes defined by the
browser and sent to the server (if no proxy, gateway, or transcoder is
in the middle). Some of the attributes that we will find useful are
listed in Table 1.
Table 1. Most common HTTP request headers
Header | Description |
---|
User-Agent | The name of the browser
or platform that originated the request |
Accept | A comma-separated
values (CSV) list of MIME types accepted by the
browser |
Accept-Charset | A CSV list of charsets
accepted by the browser (e.g., ISO-8859-1, UTF-8) |
Accept-Language | A CSV list of preferred
languages in the browser |
Accept-Charset | A CSV list of
compression methods available for the response (e.g., gzip, deflate) |
Note:
Every mobile browser supports HTTP authentication, showing a
modal window for username and password entry so the user can log
into the website.
The following is the header of a real request from a mobile
device to a server:
GET / HTTP/1.1
Host: mobilexweb.com
Accept: application/vnd.wap.wmlscriptc, text/vnd.wap.wml,
application/vnd.wap.xhtml+xml, application/xhtml+xml, text/html, multipart/mixed, */*
Accept-Charset: ISO-8859-1, US-ASCII, UTF-8; Q=0.8, ISO-10646-UCS-2; Q=0.6
Accept-Language: en
DRM-Version: 2.0
Cookie2: $Version="1"
Accept-Encoding: gzip, deflate
User-Agent: Nokia5300/2.0 (03.50) Profile/MIDP-2.0 Configuration/CLDC-1.1
x-wap-profile: "http://nds1.nds.nokia.com/uaprof/N5300r100.xml"
Warning:
Many mobile browsers send */* as the list of accepted MIME types to
avoid the server prefiltering the content that it can deliver using
the Accept header. Other mobile
browsers have known bugs in the MIME type lists that they
provide.
1.3. The user agent
The user-agent string identifies the browser. It has had
a complex history, with the result that today there are browsers that
identify themselves as six different browsers at the same time in the
same string. This somewhat complicates browser detection. There is an
excellent history of the user-agent string, presented in a very
funny way, at http://webaim.org/blog/user-agent-string-history.
In brief, as in the beginning of the web era developers often
looked for a particular string in the User-Agent header to determine what content
to deliver, many browsers, starting with Microsoft Internet Explorer,
started using a hack that today has resulted in user agent hell. The
hack was for Internet Explorer to identify itself as Mozilla (the way
that the Netscape browser, IE’s main competitor, was identified).
After this initial identification, it clarified that it was not
actually Mozilla, but rather a compatible browser (IE). Microsoft also
added other information to the user-agent string, like the operating
system and details on the plug-ins and languages supported. The end
result was a very complex user agent syntax with no standards.
In the mobile world, the situation is even worse. Some browsers
use the IE hack and identify themselves as Mozilla (with some
clarification), others identify themselves with the correct browser
name, and still others send the device brand and model number in the
User-Agent header. Even the same
device may provide a different user-agent string depending on the OS
version or the firmware used. This makes device detection using this
string a bit complex.
Note:
If you don’t want your site to be transcoded, you can use Cache-Control: no-transform both in the
HTML document and in the HTTP headers. Some transcoders use this
information to decide whether or not to transcode a document, but
there is no guarantee that this will work.
The following is a list of some mobile user-agent strings
provided by a Nokia N95, a Nokia 3510, a Motorola v3, a BlackBerry, an
iPhone 3.0, a Windows Mobile device, and a Japanese phone from the
carrier Au:
Mozilla/5.0 (SymbianOS/9.2; U;
Series60/3.1 NokiaN95/20.0.015 Profile/MIDP-2.0
Configuration/CLDC-1.1 ) AppleWebKit/413 (KHTML, like Gecko)
Safari/413
Nokia3510i/1.0 (05.30)
Profile/MIDP-1.0 Configuration/CLDC-1.0
MOT-V3i/08.B4.34R MIB/2.2.1
Profile/MIDP-2.0 Configuration/CLDC-1.1
BlackBerry8100/4.2.0
Profile/MIDP-2.0 Configuration/CLDC-1.1
VendorID/125
Mozilla/5.0 (iPhone; U; CPU like
Mac OS X; en) AppleWebKit/420+ (KHTML, like Gecko) Version/3.0
Mobile/1A538a Safari/419.3
Mozilla/4.0 (compatible; MSIE 4.01;
Windows CE; PPC; 240×320)
UP.Browser/3.04-TS14
UP.Link/3.4.4
As you can see, there is no standard for this string. So, the
initial approach is to search for some term—for example, “iPhone” or
“Symbian”—to try to determine which device or platform a request has
originated from. Don’t worry if this sounds nightmarish, though; in a
few pages we will talk about a better solution.
When the iPad (the Apple tablet) came to the market, many
thought that servers would automatically redirect iPad users to the
iPhone versions of websites, if they existed. That is because the
iPad uses iOS, just like the iPhone itself and the iPod
Touch. However, the iPad User-Agent header looks something like
this: Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) version/4.0.4 Mobile/7B367 Safari/531.21.10
As you can see, it doesn’t contain the word “iPhone,” and that
is one of the ways that developers detect usage of iPhone-based
devices. It does include the word “Mobile,” though, so if you are
looking for that word you will be able to tell that the user is on a
mobile device. That said, because the iPad has a larger screen and can show
more content than a mobile device, mobile websites are not ideal.
Some big sites have created special iPad versions using mobile
Safari extensions; these are neither the mobile nor the desktop web
versions, but somewhere in between. The iPod Touch does include “iPhone” in the user-agent string,
because it is so similar (in terms of the operating system and
screen size) to the iPhone itself. |
1.4. What we can identify
Identification is useful for context definition. We need to
remember that the user is a mobile user, and for these users the
context is very important. We want to get all the information we can
about that context, so we can provide the most useful experience
possible.
The mobile browser doesn’t send information about:
The International Mobile Equipment Identity (IMEI) or serial
number to identify the device uniquely
The type of network used (WiFi, 3G, GPRS, EDGE, CDMA)
The carrier (operator) providing service to the
device
The country of the user
If the user is roaming
The phone number of the user
The device’s brand and model number (not directly)
Some of this information (carrier, brand, and model number) can
be inferred, but the other identification data will not be available.
That is why we cannot identify users automatically without a login, as
in desktop web applications.
Note:
If you are working closely with the carrier for your mobile
website, you may be able to have yourself added to the WAP gateway’s URL whitelist. You will then be able to receive a customer
ID or phone number in a new nonstandard header.
Here’s what we can glean from the device headers:
The carrier and country, from the IP address of the request
(if it is using a 2G or 3G network).
The country (and maybe city or even location), from the IP
address of the request (if it is using a WiFi network).
The brand and model number, inferred from the User-Agent header.
The language in which the operating system is
defined.
What markups and document types are accepted, if the header
is not defined as */*.
1.5. The User Agent ProfileThe UAProf (User Agent Profile) is
a voluntary standard defined by the Open Mobile Alliance (formerly WAP
Forum). It takes the form of an XML file defining the abilities of the
device, including its screen size, download features, and markup
support.
The XML is defined by the manufacturer or the carrier, and a
link to the XML is defined in a header (typically x-wap-profile).
x-wap-profile: "http://nds1.nds.nokia.com/uaprof/N5300r100.xml"
This URL will have been defined when the browser was created,
which may have been several years before. If the URL is still working,
we should get XML like the following extract:
<prf:ImageCapable>Yes</prf:ImageCapable>
<prf:Keyboard>Qwerty</prf:Keyboard>
<prf:Model>BlackBerry 8100</prf:Model>
<prf:NumberOfSoftKeys>0</prf:NumberOfSoftKeys>
<prf:PointingResolution>Character</prf:PointingResolution>
<prf:PixelAspectRatio>1x1</prf:PixelAspectRatio>
<prf:ScreenSize>240x260</prf:ScreenSize>
<prf:ScreenSizeChar>26x18</prf:ScreenSizeChar>
UAProf files have many problems. First, we need to download the
XML for each request, process it, and either extract the properties we
want or make a local copy on our server. Second, the community has
found lots of bugs and problems in this official information. Some
devices (the iPhone, for example) don’t define a UAProf file, and they
don’t define the same properties. Also, UAProf does not have the right
granularity of information; for example, you can read that Flash is
supported, but no information is there about which version.
So, another problem added to our list.