Retry Geolocation request without refreshing the browser

左心房为你撑大大i 提交于 2019-12-11 06:56:44

问题


I have a specific issue with the Geolocation api. This is my scenario:

  1. User landed on a page ( in Chrome - Android ) with GPS location disabled.
  2. There is a button on the page, and onClick of the button triggers the Geolocation.getCurrentPosition
  3. Geolocation goes to the error callback with error message “User denied Geolocation”
  4. User goes to Android settings ( mostly in notification drawer ) and turn on the location
  5. User click the button again ( at this time, location is available ) to get the coordinates
  6. However, Geolocation api still throws the error “User denied Geolocation”

  1. At this time, the geolocation request will work only if the user refreshes the page and press the button ( note: the location is still enabled )

Is there a way to make this work without the browser refresh ?

Here is the jsbin link: https://output.jsbin.com/pihenud


回答1:


Finally, I was able to solve this problem using an iFrame hack.

Here is the solution:

Instead of asking the permission in the main window, create an iFrame dynamically and call the geolocation.getCurrentPosition inside it. Now, we can use the window.postMessage to pass the position data to the parent browser window.

When we have to retry the geolocation request again, we just need to reload the iframe -- This will have the new site settings.

Here is the iframe code if anyone wants to try:

<!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>

And in your application code, you can have a utility to inject the iFrame. See the below code:

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);
    });
  });
};


来源:https://stackoverflow.com/questions/40381742/retry-geolocation-request-without-refreshing-the-browser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!