【问题标题】:navigator.gelocation still true on iOS when location services are off当位置服务关闭时,navigator.geolocation 在 iOS 上仍然为真
【发布时间】:2019-02-28 15:26:44
【问题描述】:

我读过的所有内容都说,为了检查地理位置是否可用,检查navigator.geolocation。但是,在 iOS 上关闭了定位服务,它仍然可以通过检查。

它永远不会到达else

注意:我正在通过 https 进行测试。

if(navigator.geolocation)
{
    // on iOS safari, with location services off (globally or at the app level) this will log
    console.log('navigator.geolocation passes');
    // navigator.geolocation.getCurrentPosition does exist
    console.log(navigator.geolocation.getCurrentPosition);

    // attempt to make the call
    navigator.geolocation.getCurrentPosition((position)=>
    {
        // this will not get called
        console.log('successfully retrieved position')
    },
    (error)=>
    {
        // this will not get called
        console.log('error: ', error)
    })
}
else
{
    // I would expect this to be called but it doesn't get called
    console.log('geolocation unavailable')
}

现在,我不想在定位服务关闭时获取位置,但问题是当它们关闭时,它不应该通过检查。

我想作为最后的手段,我可​​以只为坐标设置一个变量并检查它们是否未定义或不依赖于上面的块,但如果有更好的方法来检查它,那么我想这样做。

编辑:我还应该提到,这仅在清除浏览器设置后首次加载页面时发生(至少在我的情况下)。在第一次加载时,它将通过检查然后挂起,因为不会调用任何其他内容。在第二次加载时,它似乎没有通过检查并调用了我们的后备选项。

编辑:解决方案是在检查之外设置一个变量。

// create a variable to hold the coordinates
let _coords = undefined;
// this is only a compatibility check
// not a check if it's available
if(navigator.geolocation)
{
  // on iOS safari, with location services off (globally or at the app level)
  // this block will be reached

  // attempt to make the call to getCurrentPosition
  navigator.geolocation.getCurrentPosition((position)=>
  {
    // this will not get called because location services are off
    // doing something like doSomething(position.coords) will not get called
    // instead, set the variable
    _coords = position.coords;
  },
  (error)=>
  {
    // this will not get called since it's not an error
    // doSomething(undefined);
  })
}
else
{
    // this block will not get reached since geolocation IS available,
    // just not allowed. So again,
    // doSomething(undefined) will not happen
    console.log('geolocation unavailble')
}
// pass the variable (coords or undefined) to doSomething
doSomething(coords)

以上并没有解决整个问题,因为如果用户确实开启了位置服务,getCoordinates 是异步的,因此它会在接收到坐标之前调用 doSomething 方法。

【问题讨论】:

    标签: javascript ios geolocation


    【解决方案1】:

    我认为这种检查是为了通过测试地理定位对象的存在来实现兼容性:

    // check for Geolocation support
    if (navigator.geolocation) {
      console.log('Geolocation is supported!');
    }
    else {
      console.log('Geolocation is not supported for this Browser/OS.');
    }
    

    【讨论】:

    • 我们正在测试的正是这种情况;当定位服务关闭时。我已经更新了我的代码以包含 else 语句。它已经结束了 https。
    • 我对我的帖子进行了一些更新,以更清楚地说明我预计位置服务检查会失败,因为位置服务已关闭。不过,我确实感谢您的评论。谢谢:D
    • 此代码仅检查兼容性。这将检查设备是否与地理位置兼容。
    • 是的,这也是我确定的。至少对于 iOS。我不能肯定地说,但我们的测试人员似乎没有发现非 iOS 设备存在这个问题。我还尝试在该检查中使用 try/catch,但它从未抛出错误。
    • 您需要通过识别设备操作系统来检查 navigator.geolocation.getCurrentPosition 的值
    【解决方案2】:

    我说得太早了,也太早接受了。在我的示例中,将方法移到地理位置检查之外会导致地理位置检查始终“失败”,因为getCurrentPosition 是异步的。解决方法(可以发誓我之前尝试过)是在检查中使用 try/catch。

    // geolocation
    if(navigator.geolocation)
    {
      // try to get the current position
      try {
        navigator.geolocation.getCurrentPosition((position)=>
        {
          // great success! use the coordinates
          doSomething(position.coords);
        },
        (err)=>
        {
          // failed
          console.log(err);
          // most likely due to a PositionError
          // err.code === 1 (PERMISSION_DENIED)
          doSomething();
        })
    
      } catch (err) {
        // any other error
        console.log(err);
      }
    }
    else
    {
      // geolocation not supported
      doSomething();
    }
    
    function doSomething(coords=undefined)
    {
      // ... 
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-10-03
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多