本文详解前端获取用户地理位置与IP属地的三种常见方案。首先分析navigator.geolocation API在部分环境下的局限性;其次介绍通过搜狐城市接口获取IP属地信息的实现方式及跨域处理技巧;最后演示如何结合百度地图API进行高精度定位与IP定位。对比各方案在权限弹窗、数据精度及实现复杂度上的差异,帮助开发者选择合适的位置服务策略。

写在前面
为了实现类似主流平台显示用户具体省市位置的功能,本文探讨前端获取此类信息的可行性。尽管有观点认为通信网络运营商掌握的位置数据更为准确,但本文仅关注前端技术层面的实现尝试。
尝试一:navigator.geolocation
首先尝试调用 标准地理位置接口。在实际测试中,该方法未能成功获取到预期的位置信息,具体原因可能与浏览器权限设置或环境限制有关。
getGeolocation(){
if ('geolocation' in navigator) {
/* 地理位置服务可用 */
console.log('地理位置服务可用')
navigator.geolocation.getCurrentPosition(function (position) {
console.dir('回调成功')
console.dir(position) // 没有输出
console.dir(position.coords.latitude, position.coords.longitude)
}, function (error) {
console.error(error)
})
} else {
/* 地理位置服务不可用 */
console.error('地理位置服务可用')
}
}
尝试二:sohu 的接口
接着尝试利用搜狐提供的城市信息接口 来获取用户位置。该方案成功返回了包含IP、城市ID及城市名称的数据,样本如下所示。
{"cip": "14.11.11.11", "cid": "440000", "cname": "广东省"}
// 需要做跨域处理
getIpAndAddressSohu(){
// config 是配置对象,可按需设置,例如 responseType,headers 中设置 token 等
const config = {
headers: {
Accept: 'application/json',
'Content-Type': 'application/json;charset=UTF-8',
},
}
axios.get('/apiSohu/cityjson?ie=utf-8', config).then(res => {
console.log(res.data) // var returnCitySN = {"cip": "14.11.11.11", "cid": "440000", "cname": "广东省"};
const info = res.data.substring(19, res.data.length - 1)
console.log(info) // {"cip": "14.11.11.11", "cid": "440000", "cname": "广东省"}
this.ip = JSON.parse(info).cip
this.address = JSON.parse(info).cname
})
}
在调试过程中,为了调用该接口,必须处理跨域请求问题,具体配置见下方代码。
proxy: {
'/apiSohu': {
target: 'http://pv.sohu.com/', // localhost=>target
changeOrigin: true,
pathRewrite: {
'/apiSohu': '/'
}
},
}
以下是成功获取位置信息后的界面展示效果。

尝试三:百度地图的接口
使用百度地图方案需先引入其JS依赖,并配置申请到的 参数(ak)。具体引入代码如下。
<script src="https://api.map.baidu.com/api?v=2.0&ak=3ufnnh6aD5CST"></script>
getLocation() { /*获取当前位置(浏览器定位)*/
const $this = this;
var geolocation = new BMap.Geolocation();//返回用户当前的位置
geolocation.getCurrentPosition(function (r) {
if (this.getStatus() == BMAP_STATUS_SUCCESS) {
$this.city = r.address.city;
console.log(r.address) // {city: '广州市', city_code: 0, district: '', province: '广东省', street: '', …}
}
});
}
function getLocationBaiduIp(){/*获取用户当前位置(ip定位)*/
function myFun(result){
const cityName = result.name;
console.log(result) // {center: O, level: 12, name: '广州市', code: 277}
}
var myCity = new BMap.LocalCity();
myCity.get(myFun);
}
该方案能成功获取用户的省市位置及经纬度坐标,但需要注意的是,调用浏览器定位功能时会先弹出权限征求对话框,需用户同意后方可获取。


写在后面
综合测试结果并不完全理想。搜狐接口的内部实现机制未公开,且其特点在于不会像其他方案那样弹出浏览器权限请求对话框。

相比之下,、 以及 在调用时均会触发浏览器的权限弹窗机制。
依赖第三方接口始终存在不确定性,且不清楚搜狐接口是如何绕过用户权限提示获取数据的。
经实测,搜狐接口、BMap.Geolocation() 与 BMap.LocalCity() 均可获取用户位置信息(含省市、经纬度等)。
以上即为前端获取用户位置及IP属地信息的详细实践内容,更多相关技术细节可参考本站其他文章。