如何在不请求许可的情况下获取用户的位置,或者如果用户允许一次就不需要再次询问?

新手上路,请多包涵

我正在使用 MySQL、JavaScript 和 Ajax 创建一个门户,我想根据纬度和经度获取用户的位置。如果无法在不询问的情况下获取位置,那么一旦用户授予权限,我就可以从任何页面获取位置而无需再次询问。

提前致谢。

原文由 user3406221 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 997
2 个回答

在此答案中执行此操作的 3 种方法:

  1. 获取 GPS 精确位置,要求用户允许访问其浏览器的 API
  2. 使用外部 GeoIP 服务获取大致位置(国家、城市、地区)
  3. 使用 CDN 服务获取大概位置(国家、城市、地区)

要求用户允许访问其浏览器的 API

您可以使用 HTML5 功能获取客户端的位置。如果它是从具有 GPS 的设备或大致位置完成的,这将为您提供用户的确切位置。一旦用户同意分享他的位置,您将获得它而无需再批准。此解决方案使用 Geolocation.getCurrentPosition() 。大多数情况下需要在 HTTPS 协议下执行此操作。

如果您赶时间,这里有一个带有此解决方案的 CodePen: https ://codepen.io/sebastienfi/pen/pqNxEa

 <!DOCTYPE html>
<html>
<body>

<p id="demo">Click the button to get your coordinates:</p>

<button onclick="getLocation()">Try It</button>

<script>
var x = document.getElementById("demo");

function getLocation() {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(
            // Success function
            showPosition,
            // Error function
            null,
            // Options. See MDN for details.
            {
               enableHighAccuracy: true,
               timeout: 5000,
               maximumAge: 0
            });
    } else {
        x.innerHTML = "Geolocation is not supported by this browser.";
    }
}

function showPosition(position) {
    x.innerHTML="Latitude: " + position.coords.latitude +
    "<br>Longitude: " + position.coords.longitude;
}
</script>

</body>
</html>

处理错误和拒绝 getCurrentPosition() 方法的第二个参数用于处理错误。它指定在无法获取用户位置时运行的函数:

 function showError(error) {
    switch(error.code) {
        case error.PERMISSION_DENIED:
            x.innerHTML = "User denied the request for Geolocation."
            break;
        case error.POSITION_UNAVAILABLE:
            x.innerHTML = "Location information is unavailable."
            break;
        case error.TIMEOUT:
            x.innerHTML = "The request to get user location timed out."
            break;
        case error.UNKNOWN_ERROR:
            x.innerHTML = "An unknown error occurred."
            break;
    }
}

在地图中显示结果

function showPosition(position) {
    var latlon = position.coords.latitude + "," + position.coords.longitude;

    var img_url = "http://maps.googleapis.com/maps/api/staticmap?center=
    "+latlon+"&zoom=14&size=400x300&sensor=false";

    document.getElementById("mapholder").innerHTML = "<img src='"+img_url+"'>";
}

地理IP

如果上述解决方案在您的场景中不起作用,您可以使用 IP 的位置获取一个大概的位置。您不一定会获得用户的确切位置,但最终可能会得到用户连接点区域中最近的互联网节点的位置,这对于 99% 的用例(国家、城市、地区)来说可能足够接近.

由于这不是精确的,但不需要用户的认可,这也可能满足您的要求。

找到以下 2 种方法来做到这一点。我建议使用 CDN 解决方案来执行此操作,因为它速度更快,是的,速度很重要。

使用外部 GeoIP 服务获取大致位置(国家、城市、地区)

许多外部服务允许您获取 GeoIP 位置。这是谷歌的一个例子。

要获取您的 Google API 密钥,请访问此处: https ://developers.google.com/loader/signup?csw=1

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
    <head>
        <title>Get web visitor's location</title>
        <meta name="robots" value="none" />
    </head>
    <body>
    <div id="yourinfo"></div>
    <script type="text/javascript" src="http://www.google.com/jsapi?key=<YOUR_GOOGLE_API_KEY>"></script>
    <script type="text/javascript">
        if(google.loader.ClientLocation)
        {
            visitor_lat = google.loader.ClientLocation.latitude;
            visitor_lon = google.loader.ClientLocation.longitude;
            visitor_city = google.loader.ClientLocation.address.city;
            visitor_region = google.loader.ClientLocation.address.region;
            visitor_country = google.loader.ClientLocation.address.country;
            visitor_countrycode = google.loader.ClientLocation.address.country_code;
            document.getElementById('yourinfo').innerHTML = '<p>Lat/Lon: ' + visitor_lat + ' / ' + visitor_lon + '</p><p>Location: ' + visitor_city + ', ' + visitor_region + ', ' + visitor_country + ' (' + visitor_countrycode + ')</p>';
        }
        else
        {
            document.getElementById('yourinfo').innerHTML = '<p>Whoops!</p>';
        }
    </script>
    </body>
</html>

使用 CDN 服务获取大概位置(国家、城市、地区)

大多数 CDN 都提供了使用外部服务的替代方法。这种方案的优点是不需要额外的 HTTP 请求,所以速度更快。如果您已经拥有 CDN,那么这是可行的方法。您可以使用 CloudFlare、CloudFront 等。

在这种情况下,您很可能最终将位置作为 HTTP 请求标头的参数,或者甚至直接在窗口对象中,以便您可以使用 Javascript 获取它。阅读 CDN 的文档以了解更多信息。

2018 年 12 月中旬编辑以添加更多选项。

原文由 Sébastien 发布,翻译遵循 CC BY-SA 4.0 许可协议

您可以使用 https://www.geolocation-db.com 等外部服务。他们提供基于 IP 地址的地理定位服务,您不需要用户许可。

试试这个例子:

 <!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="initial-scale=1.0, user-scalable=no"/>
<meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
<title>Geo City Locator</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
</head>
<body>
    <div>Country: <span id="country"></span></div>
    <div>State: <span id="state"></span></div>
    <div>City: <span id="city"></span></div>
    <div>Latitude: <span id="latitude"></span></div>
    <div>Longitude: <span id="longitude"></span></div>
    <div>IP: <span id="ip"></span></div>
    <script>
      $.getJSON('https://geolocation-db.com/json/')
         .done (function(location) {
            $('#country').html(location.country_name);
            $('#state').html(location.state);
            $('#city').html(location.city);
            $('#latitude').html(location.latitude);
            $('#longitude').html(location.longitude);
            $('#ip').html(location.IPv4);
         });
    </script>
</body>
</html>

原文由 Kurt Van den Branden 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题