【问题标题】:How can I get user's location without asking for the permission or if user permitted once so need not to ask ever again?如何在不请求许可的情况下获取用户的位置,或者如果用户允许一次,因此无需再次询问?
【发布时间】:2014-10-14 06:59:01
【问题描述】:

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

提前致谢。

【问题讨论】:

    标签: javascript php latitude-longitude


    【解决方案1】:

    在此答案中执行此操作的 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 的位置获取大致位置。您不一定会得到用户的确切位置,但最终可能会得到用户连接点区域中最近的 Internet 节点的位置,这对于 99% 的用例(国家、城市、地区)来说可能足够接近.

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

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

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

    许多外部服务允许您获取 GeoIP 位置。 以下是 Google 的示例。

    要获取您的 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 月中旬编辑以添加更多选项。

    【讨论】:

    • 很确定 Google API 不再返回这些对象属性。至少在我的测试中,它是在 2019 年 2 月 14 日进行的。
    • @MattTheNinja 这是真的! Google API 现在是一项付费服务​​,必须从您的选项中激活此选项...在您输入信用卡信息之后:*/
    • @MattTheNinja 最好的方法仍然是让 CDN 为您提供信息...
    【解决方案2】:

    您可以使用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>
    

    【讨论】:

    • 这提供了无限的请求还是对请求有任何限制?
    • 没有限制,允许无限请求。
    • 获取经度和纬度的最佳替代解决方案
    • 这个网站有什么好处,无限免费?他们也没有列出任何付费插件
    • 虽然是无限的,但没有的位置响应接近准确位置:(
    【解决方案3】:

    可以根据 Web 请求的源 IP 地址猜测纬度和经度。您需要访问将 IP 映射到位置的数据库或服务,例如 MaxMind 的 geoip (https://www.maxmind.com/en/geoip-demo)。应该有 JavaScript / PHP 包装器可用于您可以使用的服务。

    GeoIP 查找不是很可靠,很容易过时。如果您需要更准确的信息,则必须向用户索取一些信息,例如邮政编码。

    【讨论】:

    • IP 定位不是那么准确...如果人们使用智能手机...那么它很好,但如果人们使用网络并且提供商的位置在其他地方,那么它会给你那个位置..所以那将是错误的信息。
    猜你喜欢
    • 1970-01-01
    • 2012-01-06
    • 2013-03-15
    • 2020-05-26
    • 2017-04-14
    • 1970-01-01
    • 2019-12-01
    • 2013-05-10
    • 1970-01-01
    相关资源
    最近更新 更多