使用geolocation API定位你的访问者位置
今天要说一个跨省的好东西玩玩。
那就是geolocation,W3C对geolocation的解释是“defines an API that provides scripted access to geographical location information associated with the hosting device”。Firefox从3.5起就支持geolocation了,习惯赶时髦的opera也发布了一个支持geolocation的版本,几天前Chrome dev 5也正式支持geolocation了。如果你的浏览器被鄙视了也可以使用google gears的Geolocation API曲线救国来玩(关于这一点请参考JerryQu同学早一段时间写的文章)。于是记录和朋友们分享下。
如果你有兴趣可以使用上面提到的浏览器点击这里看个简单的demo。
简单说下前端的实现吧,主要代码如下:
function displayPosition(position) {
//得到两个值:position.coords.longitude(经度)、position.coords.latitude(维度)。
/*任意鞣虐得到的经纬度信息来展示你想要的样子吧。
*/
}
navigator.geolocation.getCurrentPosition(displayPosition);
geolocation的原理就是收集你上网的终端设备的某些信息发送到特定的服务接口用来查询以获得你的地理信息,如果你是使用的是无线wifi上网的方式,发送的信息如JerryQu提到的一样,大致如下(Firefox下的抓包):
post http://www.google.com/loc/json
post_data='{"version":"1.1.0",
"request_address":true,
"access_token":"2:OLzIuqa-P8tZYOpu:Gu-LV8OcMFK28CVE",
"wifi_towers":[
{
"mac_address":"00-23-eb-b7-ef-70",
"ssid":"abc","signal_strength":-45
},
{
"mac_address":"00-23-eb-b7-ef-72",
"ssid":"abc_Guest","signal_strength":-48
}
]
}=';
返回的信息类似如下(可以查看我通过curl脚本模拟的数据 http://www.ivershuo.com/did/geolocation/loc.php):
{
"location":
{
"latitude":40.0475799,
"longitude":116.2947221,
"address":{
"country":"China",
"country_code":"CN",
"region":"Beijing",
"city":"Beijing",
"street":"Tangjialing Rd"
},
"accuracy":278.0
}
}
可以发现firefox也是使用的google的loc接口,如果你提供的access_token值为空或者是错误的在respone的时候会给你返回一个正确的access_token(该值是2周有效的)。wifi_towers包含了你的wifi信息数组用来判断你离热点们(?)的距离等信息。如果你使用的是有线上网的方式会发现传送的wifi_towers数组是空的,但是也会返回地理位置的值,应该是通过ip来返回的(因为我使用服务器脚本去请求该接口的时候返回的是服务器所在地的地理信息),所以偏差很大。现在还不知道是不是可以传送gps数据,有条件的同学可以试试在android手机上验证可以使用gps数据。
不过照前面的demo来看,就算是wifi的方式得到的位置信息还是有一定的偏差(这中间也有不同地图服务的定位信息的偏差),但是比ip获得的位置已经精确很多了。对位置信息精确度教高的web应用可以试点应用玩玩。
回到开头的那句话,大家不要担心跨省,因为浏览器在发送这个信息的时候会先要获得你的授权的。
p.s1:要使用geolocation:Firefox浏览器需要保证about:config中geo.enabled的值为true,chrome dev需要带参数“"--enable-geolocation"”启动。
p.s2:如果你也想构造数据请求google的loc接口,需要保证数据是以application/json的格式请求的。