收藏
回答

在公众号 H5 中,wx.getLocation 获取定位偶发失败的根因有哪些?

我在公众号 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;
        });


      }
回答关注问题邀请回答
收藏

1 个回答

  • 社区技术运营专员--许涛
    社区技术运营专员--许涛
    03-24

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

    03-24
    有用
    回复
登录 后发表内容