前言
由于业务需要,企微PC端页面应用需要获取地理位置,然后发现并不支持,如下方官方回复,今天小编也顺便收集整理了一下浏览器获取地址位置的内容整理成文章。
既然不支持的话,我们使用浏览器的定位又是怎么样的呢?
浏览器对获取位置的支持性如何?
目前浏览器提供了一个获取地理位置的接口,该接口用于获取用户的经纬度信息,他有三个参数,分别是成功回调、失败回调、以及配置项。
navigator.geolocation.getCurrentPosition(function(res){},function(err){},options)
调用后浏览器会收到获取位置授权的确认消息。注意仅在浏览器刷新后只用调用一次,如果点击了不允许,则后续不刷新跳转一直获取的都是失败的消息。下图以safari为例。(Google会在右上角的搜索栏区域显示位置状态icon)
chrome浏览器则需要https域名才能唤起弹窗,然后没有那么简单,很遗憾的是我们主流的Google chrome浏览器居然还是不支持,真是离了大谱,最后发现是因为google调用了自身的一个api,因为Google早些年就被大陆禁用,可想而知,基本上是访问不通的。(小编也是使用了VPN翻墙发现位置获取通了,可是产品给用户怎么能行?)
企业微信使用的是什么浏览器内核?
小编这里使用了fiddler对数据请求进行了抓包,并拦截请求结果返回了我本地的界面,遗憾的是结果与谷歌完全一致,通过百度地图最多也只是获取到市。
拦截代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
hello world
</body>
<script src="//api.map.baidu.com/api?type=webgl&v=1.0&ak=xx你的AKxxxx"></script>
<script>
var geolocation = new BMapGL.Geolocation();
geolocation.getCurrentPosition(function(r){
document.body.append('城市:'+ r.address.city+'QU:'+ r.address.district+'LU'+r.address.street)
});
</script>
</html>
企微显示:
其他浏览器的显示:
发现了企业微信社区官方的回复,使用的chrome内置浏览器,我们看到的打开外置浏览器只是企微获取的默认浏览器而已,其内置的浏览器支撑打开的网页应用还是chrome。
百度地图、高德地图的定位如何?
开始登录尝试各大地图开发者平台的精准定位,发现同样的遭遇了“滑铁卢”。
很明显安装百度地图所说的,浏览器定位是失败了,我们也得到了一个结论,无论是百度还是高德都是基于底层浏览器定位而二次开发封装获取的地理位置,那么失败了就没救了嘛?根据文档显示可以走IP定位,事实上IP定位开放的基本上都是到市级别的,也不是精准定位啊,我要它还有啥用,绝望中。。。
百度地图带来意外的一线生机
当我们打开电脑端的百度地图时,右下角出现了一个定位我的位置,好家伙,直接就定位到了我的具体位置,基本上误差很小,我的兴趣又来了。。。
开启疯狂试探的验证模式
- 在手机验证码登录才能连接的私有wifi模式下,精准定位失败
- 手机热点模式下,定位出现了偏差,距离在20公里不等
嗯,开始有点意思了,不同网络下展示的情况不通,正常的局域网网络(常规的wifi、网线)是ok的,需要手机验证的私有WiFi失败,手机流量出现定位偏差。
结论:在精准定位失败后,百度地图尝试的是根据网络来获取的位置,小编之所以尝试流量是因为移动网络所连接的基站会有所不同,所以此模式的定位通常会出现大的偏差,果然,如我所想。
功夫不负有心人
挖掘到百度地图没有公开的api,这是一个get请求,t为时间戳,不过好像不加也可以。现在已经不支持jsonp跨域了,需要通过配置代理来解决跨域,获取精准的地理位置。经过以上几种模式的尝试,与百度地图获取定位的结果完全一致,正是采用了该接口。大家也不用过于担心不稳定,据搜索的资料显示,有人在19年使用的是该接口,目前还从来没有发生过变更。
https://map.baidu.com/?qt=ipLocation&t=1618482557945
请求结果实例:
{
"ipLoc": {
"content": {
"location": {
"lat": 3640647,
"lng": 13520609
},
"locid": "0dac913fc59fdbcf497ec9c5a31470ab",
"radius": 0,
"confidence": 1,
"ip_type": 2,
"point": {
"x": 13520609,
"y": 3640647
}
},
"result": {
"error": 161,
"loc_time": "2022-09-08 22:20:54"
},
"status": "success",
"message": "request hpiploc server[iploc] success",
"code": 0,
"time": 18
},
"rgc": {
"status": "success",
"result": {
"location": {
"lng": 121.45637560976,
"lat": 31.232694824131
},
"formatted_address": "上海市静安区铜仁路254号",
"business": "北京西路,南京西路,静安寺",
"addressComponent": {
"country": "中国",
"country_code": 0,
"country_code_iso": "CHN",
"country_code_iso2": "CN",
"province": "上海市",
"city": "上海市",
"city_level": 2,
"district": "静安区",
"town": "",
"town_code": "",
"distance": "1",
"direction": "附近",
"adcode": "310106",
"street": "铜仁路",
"street_number": "254号"
},
"pois": [{
"addr": "铜仁路258号九安广场金座7楼c-d座",
"cp": " ",
"direction": "附近",
"distance": "30",
"name": "九安广场金座7楼C-D座",
"poiType": "房地产",
"point": {
"x": 121.45664510141,
"y": 31.232671665929
},
"tag": "房地产;写字楼",
"tel": "",
"uid": "6b360d0877725791077ce881",
"zip": "",
"parent_poi": {
"name": "",
"tag": "",
"addr": "",
"point": {
"x": 0,
"y": 0
},
"direction": "",
"distance": "",
"uid": ""
}
}],
"roads": [],
"poiRegions": [],
"sematic_description": "九安广场金座7楼C-D座附近30米",
"cityCode": 289
},
"code": 0,
"message": "request geocoder\/v2 success",
"time": 13
}
}
该请求无需进行地理位置授权,目前好像也只能以此接口作为pc端的地理位置获取了,因为常规的电脑都是局域网连接。弊端嘛就是,如果流量开的热点就会有偏差,手机短信验证的私有WiFi依然会获取失败。你get到了嘛?