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

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

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

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

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

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

【问题讨论】:

    标签: javascript geolocation


    【解决方案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);
        });
      });
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-11-26
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多