重试地理定位请求而不刷新浏览器

Posted

技术标签:

【中文标题】重试地理定位请求而不刷新浏览器【英文标题】:Retry Geolocation request without refreshing the browser 【发布时间】:2016-11-02 13:56:01 【问题描述】:

我对 Geolocation api 有一个特定的问题。这是我的场景:

    用户登陆的页面(在 Chrome - android 中)禁用了 GPS 定位。 页面上有一个按钮,按钮的onClick触发Geolocation.getCurrentPosition 地理位置转到错误回调,并显示错误消息“用户拒绝地理位置” 用户转到 Android 设置(主要在通知抽屉中)并打开位置 用户再次点击按钮(此时位置可用)获取坐标 但是,Geolocation api 仍然会抛出错误“User denied Geolocation”

    此时,地理定位请求只有在用户刷新页面并按下按钮时才会起作用(注意:定位仍然有效)

有没有办法在不刷新浏览器的情况下完成这项工作?

这里是jsbin链接:https://output.jsbin.com/pihenud

【问题讨论】:

【参考方案1】:

最后,我能够使用 iFrame hack 解决这个问题。

解决办法如下:

不是在主窗口中询问权限,而是动态创建一个 iFrame 并在其中调用geolocation.getCurrentPosition。现在,我们可以使用window.postMessage 将位置数据传递给父浏览器窗口。

当我们不得不再次重试地理定位请求时,我们只需要重新加载 iframe -- 这将具有新的网站设置。

如果有人想尝试,这里是 iframe 代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Namshi Geolocation</title>
</head>
<body>
  <script type="text/javascript">
    var sendMessage = function(result)
      window.postMessage(JSON.stringify(result), window.location.origin);
    ;

    var triggerGeolocationRequest = function()
      var options = 
        enableHighAccuracy: true,
        timeout: 10000,
        maximumAge: 0
      ;

      var result;

      if(window.navigator.geolocation)
        window.navigator.geolocation.getCurrentPosition(function(position)
          var result = 
            type: 'success',
            data: lat: position.coords.latitude, lng: position.coords.longitude
          ;
          sendMessage(result);
        , function(err)
          var result = 
            type: 'error',
            data:  message: err.message, code: err.code 
          ;
          sendMessage(result);
        , options)
       else 
        result = 
          type: 'error',
          data:  message: 'No Geolocation API' 
        ;
        sendMessage(result);
      
    ;
    window.addEventListener('load', triggerGeolocationRequest);
  </script>
</body>
</html>

在您的应用程序代码中,您可以使用一个实用程序来注入 iFrame。见以下代码:

utils.getCurrentPosition = function()
  return new Promise(function(resolve, reject)
    var ifr = document.createElement('iframe');
    ifr.style.opacity = '0';
    ifr.style.pointerEvents = 'none';
    ifr.src = location.origin + '/geo.html'; // the previous html code.

    document.body.appendChild(ifr);

    ifr.contentWindow.addEventListener('message', function(message)
      message = JSON.parse(message.data);
      if(message.type === 'success')
        resolve(message.data);
       else 
        reject(message.data);
      
      document.body.removeChild(ifr);
    );
  );
;

【讨论】:

以上是关于重试地理定位请求而不刷新浏览器的主要内容,如果未能解决你的问题,请参考以下文章

浏览器允许/禁止地理定位请求按钮

如何使用 Gmap 在浏览器地理定位中处理用户批准?

用户地理位置 - 案例研究

来自 3rd 方脚本的 html5 地理定位权限

ionic2:浏览器中的地理定位失败并出现错误:异常:未捕获(承诺中):错误

地理定位在笔记本电脑上工作,但不在智能手机上