我在公众号 H5 页面里做了考勤打卡,定位使用的是 wx.getLocation。
线上出现一个“低频但持续”的问题,想请教会有哪些原因导致的
1. 现象描述
日活打卡人数约 600 人/天,每天会有少量用户(约几人)出现定位失败,失败后并非永久,用户稍后重试/重新进入页面后通常可以恢复,iOS/Android/鸿蒙 都有
2. 业务场景流程
进入页面后调用 wx.getLocation({ type: 'gcj02' }) 获取经纬度,再做逆地理解析和打卡范围判断,当前前端设置了定位超时(5 秒),超时后提示失败
3. 用户侧常见反馈
失败时我们会提示用户检查权限,部分用户按以下步骤可恢复:
微信「我-设置-个人信息与权限-系统权限管理-位置」
改成“每次询问”
重新进入页面并授权
但并不是每次都稳定复现,整体属于“偶发”。因为即使用户不操作,它过一段时间后也会恢复正常。
4.想请教的问题
在公众号 H5 中,wx.getLocation 偶发失败的常见根因有哪些?
(如系统定位权限状态、微信客户端策略、网络抖动、机型兼容、签名时效等)
对于“低频偶发失败但稍后恢复”的场景,推荐的重试策略是什么?
超时建议值(5 秒是否过短?)
是否建议失败后自动重试(例如 1~3 次 + 退避)
是否建议把“经纬度获取成功”和“逆地理解析成功”分开处理
是否有官方建议的错误分类方式(基于 fail errMsg)和排查清单?
如果有官方文档链接、典型案例或建议配置,非常感谢!
下面是涉及到定位的考勤打卡的代码
//获取定位
getAddress() {
let that = this;
const timeoutPromise = new Promise((_, reject) => {
setTimeout(() => {
reject(new Error('定位超时'));
}, 5000); // 5秒超时时间
});
const locationPromise = new Promise((resolve, reject) => {
wx.getLocation({
type: "gcj02", // 默认为wgs84的gps坐标,如果要返回直接给openLocation用的火星坐标,可传入'gcj02'
IsHighAccuracy: true,
success: function (res) {
// console.log(res);//iOS给的坐标是number 安卓给的坐标是string
const wgs84Loc = that.gcj02towgs84(Number(res.longitude), Number(res.latitude))
that.jdNow = res.longitude; // 经度,浮点数,范围为180 ~ -180。
that.wdNow = res.latitude; // 纬度,浮点数,范围为90 ~ -90
// that.$notify({ type: 'success', message: '获取地址成功' + that.jdNow + ',' + that.wdNow });
that.geocoder(wgs84Loc[1], wgs84Loc[0]); // 地址解析
// 判断是否进入考勤地点
let distance = []
for (let i = 0; i < that.initData.location.length; i++) {
const e = that.initData.location[i]
distance.push(that.latlngDiff(that.wdNow, that.jdNow, e.latitude, e.longitude))
}
var index = distance.indexOf(Math.min.apply(Math, distance))
that.workLocInfo = that.initData.location[index]
that.isWorkLoc = false
// 不按考勤点的距离选取打卡点,而是遍历考勤点只要找到在范围内的即可打卡
for (let i = 0; i < that.initData.location.length; i++) {
if (distance[i] <= that.initData.location[i].offset) {
that.inWorkLoc = that.initData.location[i].title
that.isWorkLoc = true
break;
}
}
that.addressShow = true
resolve()
},
fail: function (err) {
reject(err);
}
});
})
return Promise.race([locationPromise, timeoutPromise]).catch(err => {
that.loading = that.refreshLoading = false
that.addressShow = false
that.address = ''
that.getAddrErr = true;
that.$dialog.alert({
title: err.message === '定位超时' ? '定位超时' : '定位失败',
message: '请检查是否已打开手机定位功能、授权微信APP定位权限、授权公众号使用定位等',
theme: 'round-button',
}).then(() => {
clearInterval(that.intervalBox2);
});
throw err;
});
}

你好,没有相关文档,根据返回的fail判断,若还有问题提供下fail