Javascript 如何在不征求许可的情况下获取用户的位置,或者如果用户允许一次,则无需再次询问?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/26354472/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I get user's location without asking for the permission or if user permitted once so need not to ask ever again?
提问by Kurt Van den Branden
I am creating a portal using MySQL, JavaScript and Ajax and I want to fetch user's location in terms of latitude and longitude. if it is not possible to fetch the location without asking then once user grant the permission, I could fetch the location from any page without asking ever again.
我正在使用 MySQL、JavaScript 和 Ajax 创建一个门户,我想根据纬度和经度获取用户的位置。如果在不询问的情况下无法获取位置,那么一旦用户授予权限,我就可以从任何页面获取位置,而无需再次询问。
Thanks in Advance.
提前致谢。
回答by Sébastien
3 ways to do this in this answer:
在此答案中执行此操作的 3 种方法:
- Get a GPS precise location asking the user to allow access to its browser's API
- Get an approximate location (country, city, area) using an external GeoIP service
- Get an approximate location (country, city, area) using CDN service
- 获取 GPS 精确位置,要求用户允许访问其浏览器的 API
- 使用外部 GeoIP 服务获取大致位置(国家、城市、地区)
- 使用 CDN 服务获取大致位置(国家、城市、地区)
Ask the user to allow access to its browser's API
要求用户允许访问其浏览器的 API
You can get the location of the client using HTML5 features. This will get you the exact location of the user if it is done from a device which has a GPS, or an approximate location. Once the user approved to share his location, you'll get it without any more approval. This solution uses Geolocation.getCurrentPosition(). It is required for most cases to do this under HTTPS protocol.
您可以使用 HTML5 功能获取客户端的位置。如果它是从具有 GPS 的设备或近似位置完成的,这将为您提供用户的确切位置。一旦用户批准分享他的位置,您无需再获得任何批准即可获得该位置。此解决方案使用Geolocation.getCurrentPosition()。大多数情况下需要在 HTTPS 协议下执行此操作。
If you are in a hurry, here is a CodePen with this solution: https://codepen.io/sebastienfi/pen/pqNxEa
如果您赶时间,这里有一个带有此解决方案的 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>
Handling Errors and RejectionsThe second parameter of the getCurrentPosition() method is used to handle errors. It specifies a function to run if it fails to get the user's location:
处理错误和拒绝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;
}
}
Displaying the Result in a Map
在地图中显示结果
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+"'>";
}
GeoIP
地理IP
If the solution above doesn't work in your scenario, you can obtain an approximate position using IP's location. You will not necessarily get the exact location of the user, but may end up with the location of the nearest Internet node in the user's connection point area, which may be close enough for 99% of the use cases (country, city, area).
如果上述解决方案在您的场景中不起作用,您可以使用 IP 的位置获取大致位置。您不一定会获得用户的确切位置,但最终可能会得到用户连接点区域中最近 Internet 节点的位置,这对于 99% 的用例(国家、城市、区域)来说可能足够接近.
As this is not precise but doesn't require the user's approval, this may also meet your requirements.
由于这并不精确但不需要用户的批准,因此这也可能满足您的要求。
Find below 2 ways to do that. I would recommend doing this using the CDN solution because it is faster and yes, speed matters a lot.
找到以下 2 种方法来做到这一点。我建议使用 CDN 解决方案来执行此操作,因为它更快,而且是的,速度很重要。
Get an approximate location (country, city, area) using an external GeoIP service
使用外部 GeoIP 服务获取大致位置(国家、城市、地区)
Many external services allows you to obtain the GeoIP location. Here is an example with Google.
许多外部服务允许您获取 GeoIP 位置。这是谷歌的一个例子。
To get your Google API Key, go here: https://developers.google.com/loader/signup?csw=1
要获取您的 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>
Get an approximate location (country, city, area) using CDN service
使用 CDN 服务获取大致位置(国家、城市、地区)
An alternative to using external services is provided by most of the CDN. The advantage of this solution is that no extra HTTP request is required, so it is faster. If you already have a CDN, this is the way to go. You can use CloudFlare, CloudFront, etc.
大多数 CDN 都提供了使用外部服务的替代方法。这种方案的优点是不需要额外的 HTTP 请求,所以速度更快。如果您已经拥有 CDN,那么这就是您要走的路。您可以使用 CloudFlare、CloudFront 等。
In this scenario, you will most likely end up with the location as a parameter of the HTTP request's header, or even directly in the window object so you can get it with Javascript. Read the CDN's documentation to know more.
在这种情况下,您很可能最终将位置作为 HTTP 请求标头的参数,或者甚至直接在 window 对象中,以便您可以使用 Javascript 获取它。阅读 CDN 的文档以了解更多信息。
Edited on mid December 2018 to add more options.
于 2018 年 12 月中旬编辑以添加更多选项。
回答by Kurt Van den Branden
You can go for an external service like https://www.geolocation-db.com. They provide a geolocation service based on IP addresses where you don't need user permission.
您可以使用https://www.geolocation-db.com 之类的外部服务。它们提供基于 IP 地址的地理定位服务,您不需要用户许可。
Try this example:
试试这个例子:
<!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>
回答by FoolishSeth
It's possible to guess latitude and longitude based on the origin IP address of a web request. You need access to a database or service which maps IPs to locations, such as MaxMind's geoip (https://www.maxmind.com/en/geoip-demo). There should be JavaScript / PHP wrappers available for services such as these which you can make use of.
可以根据 Web 请求的原始 IP 地址猜测纬度和经度。您需要访问将 IP 映射到位置的数据库或服务,例如 MaxMind 的 geoip ( https://www.maxmind.com/en/geoip-demo)。应该有 JavaScript / PHP 包装器可用于诸如这些您可以使用的服务。
GeoIP lookup is not very reliable and can get out of date easily. If you need something more accurate you'll have to solicit some information from the user, such as a zip code.
GeoIP 查找不是很可靠,很容易过时。如果您需要更准确的信息,则必须向用户索取一些信息,例如邮政编码。

