浅析H5获取用户定位的四种方式:navigator.geolocation、腾讯地图前端定位组件、ip定位、微信的jssdk定位
一、web端的定位方式分类
web端定位的方式,大概可以分为下面三类:
- H5原生:navigator.geolocation
- IP定位:用IP通过CGI接口获取定位
- app定位:app获取定位再传给前端
基于这三类,我们可以采用下面方式这些来进行位置定位。
1、navigator.geolocation:H5的原生定位即navigator.geolocation。
2、腾讯地图前端定位组件:基于navigator.geolocation做了一些封装,如果原生定位失败,会降级用ip获取定位,同时也对获取的位置信息做了一些缓存的优化。
3、腾讯地图IP定位API:通过CGI接口请求得到一个精确度比较低的位置信息。
4、微信的jssdk:微信提供了jssdk,H5可以直接调用获取到位置信息。本质上是通过jsbridge传递app获取到位置信息。同理,我们也可以通过url参数等其他方式,来传递app获取到的位置信息。
二、navigator.geolocation
文档:https://developer.mozilla.org/zh-CN/docs/Web/API/Navigator/geolocation
// H5原生的位置定位
export default class TencentMapApiLocation implements LocationInterface {
getLocation(): Promise<LocationResult> {
return new Promise((resolve, reject) => {
function geoShowPosition(position) {
if (position) {
const location = { lat: position.coords.latitude, lng: position.coords.longitude };
resolve({ location, flag: LocationFlag.LocationSuccss });
} else {
reject();
}
}
function geoShowError(error) {
console.log(`getPosError:${error.code},${navigator.geolocation},${error.message}`);
reject();
}
navigator.geolocation.getCurrentPosition(geoShowPosition, geoShowError);
});
}
}
优点:(1)不依赖外部接口和组件,位置信息准确(2)是否能获取到位置信息,与内嵌H5的app是否开启定位授权强相关,不会出现关闭定位授权,还能获取到定位的情况。
缺点:(1)用户拒绝H5的授权弹窗后,需要用户重置系统权限才能获取到定位授权(重新开启app的授权设置也是没用的)。(2)H5的定位授权弹窗的是浏览器弹出的,文案不能自定义,没办法在这个弹窗向用户说明获取位置信息是用在什么地方。
适用场景:navigator.geolocation适用于大多数的获取定位的场景,而且其能否获取到定位,完全和用户是否给app开启位置授权有关,不用担心app在合规检查中出现问题。
问题1.为什么我开了app的定位授权,但是H5上却获取不到用户位置定位信息?
这是因为H5调用navigator.geolocation获取定位,除了需要app开启授权,还需要“浏览器的授权”。
问题2.为什么我进页面的时候会弹H5的定位授权弹窗,这个弹窗上的文字可以改吗?
不能。
问题3.我拒绝了H5的定位授权弹窗,要怎么再弹出来授权弹窗?
移动端浏览器的授权弹窗被用户拒绝后,需要“重置系统的定位设置”,才能重新弹出这个弹窗。
在iOS,重置定位权限的操作路径是:系统-通用-还原-还原位置和隐私。
三、腾讯地图前端定位组件
// 用腾讯地图sdk获取位置
export default class TencentMapLocation implements LocationInterface {
public getLocation(options: LocationOptions): Promise<LocationResult> {
return new Promise((resolve, reject) => {
function geoShowPosition(location) {
resolve({ location, flag: LocationFlag.LocationSuccss });
}
function geoShowError() {
reject();
}
loader('https://3gimg.qq.com/lightmap/components/geolocation/geolocation.min.js', () => {
// eslint-disable-next-line no-undef
const geolocation = new (window as any).qq.maps.Geolocation(
tencentMapConfig.GEO_KEY,
tencentMapConfig.GEO_REFERER,
);
const tencentMapOptions = {
timeout: options.timeout,
};
geolocation.getLocation(geoShowPosition, geoShowError, tencentMapOptions);
});
});
}
}
优点:(1)腾讯地图前端定位组件是在原生H5定位的基础上做了一下优化,包括对获取的位置信息做了缓存,当原生H5定位失败的时候(用户未授权app权限或者拒绝了授权弹窗),会降级使用IP定位。(2)和原生相比,获取信息的成功率会有一定的提高。
缺点:(1)用户是否能获取到位置信息,与是否开启app的定位授权不是强相关的。用户关闭了app的定位授权,仍然可以通过缓存和ip定位获取到位置信息。(2)因为是优先使用H5原生定位,依然会弹出H5的定位授权弹窗。
适用场景:适用于对LBS依赖比较高的业务,在几种定位方式中,是首选的定位方式。由于位置信息的获取,与用户是否授权app不强相关,在合规检查中可能会有风险。
问题1. 为什么我关了app的定位授权,但是H5上还是获取到了用户位置信息?
由于腾讯地图前端定位组件的优化,在用户关闭app定位授权的时候,依旧可以通过ip定位和缓存获取到位置信息。
由于我们的业务是嵌入在多个app中,最近经常需要配合app修改页面以通过合规检查,常用的修改方案是改用navigator.geolocation获取位置信息,或者直接用app获取的位置信息。
四、微信sdk定位
// 用微信sdk获取用户位置信息
export default class WechatSdkLocation implements LocationInterface {
public getLocation(): Promise<LocationResult> {
return new Promise((resolve, reject) => {
configWx(['getLocation', 'openLocation'], []).then((wx) => {
const tmp = {
type: 'gcj02',
success(res) {
const location = {
lat: parseFloat(res.latitude),
lng: parseFloat(res.longitude),
};
resolve({ location, flag: LocationFlag.LocationSuccss });
},
fail(error) {
console.log('WechatSdkLocation', error);
reject();
},
};
wx.getLocation(tmp);
})
.catch((error) => {
console.log('WechatSdkLocation', error);
reject();
});
});
}
}
优点:(1)速度快,精确度高,成功率高(2)不会有定位授权弹窗(3)是否能获取到位置信息,完全和app是否授权相关。
缺点:没有,在微信webview直接用这个就好了。
适用场景:只有微信webview,使用前需要注入微信js-sdk的配置信息。
在其他app中使用:这种定位方式的本质是直接使用app的定位能力,同理在其他的app中,我们也可以用类似的方式来获取位置信息。需要做的就是app和H5之间的消息传递,通过url参数、jsBridge等等,实现的方式很多。
五、腾讯地图API的IP定位
// 用腾讯地图api通过IP获取用户位置信息
export default class TencentMapApiLocation implements LocationInterface {
public getLocation(): Promise<LocationResult> {
return new Promise((resolve, reject) => {
axios.get(`https://apis.map.qq.com/ws/location/v1/ip?key=${tencentMapConfig.GEO_KEY}`).then((res) => {
const result = (res?.data?.result) || {};
const location = (result?.location) || {};
if (location) {
resolve({ location, flag: LocationFlag.LocationIpSuccss });
} else {
reject();
}
})
.catch((error) => {
console.log('TencentMapApiLocation', error);
reject();
});
});
}
}
优点:(1)成功率高(2)不需要H5授权弹窗,不需要app授权
缺点:(1)精确度低,一般都只有市级的经纬度(2)API接口的请求次数有限额,企业用户可以申请到300w次/日的配额
适用场景:适用于对精确度要求不高的业务,IP定位一般在服务端使用,可以作为其他定位方法的降级方案,如果前端获取不到用户位置信息,服务端再用ip定位去拉取LBS业务的数据。由于有限额,服务端可以对单个ip的位置信息做一下缓存优化,减少配额的使用。

浙公网安备 33010602011771号