HTML5: Geolocation API

The Geolocation API specification has one of the best cross-browser support percentages of all HTML5 functionality. On ~81% of all browsers, some dating back 24 versions, it remains one of the most dependably implemented systems. However, even with all of this support, it comes with a major caveat and some often subtle problems.

For those browsers running within a context that have access to a GPS or similar device, the geolocation data will come from that source. Assuming the user has given permission for the application to do so, and especially on many mobile devices, the data supplied to the API will come from something local, either software or hardware related. This will all be handled in-code.

For those contexts without this access, though, the API will silently fall back to using online geolocation services, often Google’s. And on face value, this may not seem so bad. However, the specification dictates that semi-identifiable data like IP addresses and even access point names be sent in to determine location. Such information, depending on the location and user in question, has the possibly to “leak” much more than was intended.

Using such services also introduces the need to be connected to an outside network as well, negating the ability to go offline or disconnect from the Internet. Again, this is less of an issue for mobile devices with location services, but has the potential to introduce problems for those with such services turned off or for non-mobile users in certain settings.

/*
* A Geolocation object
*
* Note: Uses GPS or similar hardware for data if available through
* the browser, but will fall back to using (Google) geolocation
* services with current IP address automatically.
*
* @property {boolean} supported If the geolocation functions are available in the current context
* @property {function} onsuccess The function to be called if the geolocation services are successful
* @property {function} onerror The function to be called if an error occurs
* @property {object} options The options {enableHighAccuracy, maximumAge, timeout} to apply to geolocation functions
* @property {object} position The last recorded geolocation data (default is 0)
*/
var Geolocation = (function(self) {
self.supported = ("geolocation" in navigator);
self.onsuccess = function() {};
self.onerror = function() {};
/*
* The accuracy, maximum age, and timeout for the geolocation data
*/
self.options = {
enableHighAccuracy: true,
maximumAge: 30000,
timeout: 27000
};
/*
* The last recorded geolocation
*/
self.position = {
latitude: 0,
longitude: 0
};
/*
* The watchPosition function ID, if set
*/
var wpid = null;
/*
* Gets the current geolocation position, recording the data
* and calling associated functions
*/
self.getCurrentPosition = function() {
if (self.supported) {
navigator.geolocation.getCurrentPosition(function(position) {
self.position.latitude = position.coords.latitude;
self.position.longitude = position.coords.longitude;
self.onsuccess.apply(this, arguments);
}, self.onerror, self.options);
}
};
/*
* Watches the geolocation position, calling the onsuccess function
* according to the maximumAge and timeout options
*/
self.watchPosition = function() {
if (self.supported) {
wpid = navigator.geolocation.watchPosition(function(position) {
self.position.latitude = position.coords.latitude;
self.position.longitude = position.coords.longitude;
self.onsuccess.apply(this, arguments);
}, self.onerror, self.options);
}
};
/*
* Clears (if set) the currently watched position function
*/
self.clearPosition = function() {
if (self.supported && wpid !== null) {
navigator.geolocation.clearWatch(wpid);
}
};
return self;
})(Geolocation || {});
view raw geolocation.js hosted with ❤ by GitHub