如何使用地理定位系统获取访客的位置(即国家) ?

我正在尝试扩展本地地理定位功能

if(navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
});
}

这样我就可以使用访问者的国家名称(也许返回一个信息数组)。

到目前为止,我已经能够找到的所有功能,显示谷歌地图界面,但没有实际给我想要的,除了 这个图书馆工作得很好的 在这个例子中,但由于某些原因不能在我的计算机上工作。我不知道为什么会出错。

无论如何,你知道我如何简单地从经纬度返回一个包含国家、城市等信息的数组吗?

328708 次浏览

如果只需要用户的国家,则不需要定位用户。您可以在任何 IP 到位服务(如 Maxmind注册Ip2location)中查找他们的 IP 地址。这在大多数情况下是准确的。

下面是 Ipregistry 的客户端示例(免责声明,我正在为此工作) :

fetch('https://api.ipregistry.co/?key=tryout')
.then(function (response) {
return response.json();
})
.then(function (payload) {
console.log(payload.location.country.name + ', ' + payload.location.city);
});

如果你真的需要获取他们的位置,你可以用这种方法获取他们的 lat/lng,然后查询 谷歌的或者 雅虎反座标化服务。

ws.geonames.org提供了一个非常容易使用的服务:

http://ws.geonames.org/countryCode?lat=43.7534932&lng=28.5743187&type=JSON

下面是我添加到代码中的一些(jQuery)代码:

if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(function(position) {
$.getJSON('http://ws.geonames.org/countryCode', {
lat: position.coords.latitude,
lng: position.coords.longitude,
type: 'JSON'
}, function(result) {
alert('Country: ' + result.countryName + '\n' + 'Code: ' + result.countryCode);
});
});
}​

试试 jsfiddle.net频道。

你可以用我的 http://ipinfo.io服务。它将提供客户端 IP、主机名、地理位置信息(城市、地区、国家、区号、邮政编码等)和网络所有者。下面是一个记录城市和国家的简单示例:

$.get("https://ipinfo.io", function(response) {
console.log(response.city, response.country);
}, "jsonp");

下面是一个更详细的 JSFiddle 示例,它还打印出完整的响应信息,因此您可以看到所有可用的详细信息: http://jsfiddle.net/zK5FN/2/

位置通常不如本地地理位置详细信息准确,但它不需要任何用户权限。

您可以使用您的 IP 地址获取您的“国家”,“城市”,“ isp”等..。
只需使用其中一个 Web 服务,它为您提供了一个简单的 api,比如 http://ip-api.com,它在 http://ip-api.com/json上为您提供了一个 JSON 服务。简单地发送一个 Ajax (或 Xhr)请求,然后解析 JSON 以获得您需要的任何数据。

var requestUrl = "http://ip-api.com/json";


$.ajax({
url: requestUrl,
type: 'GET',
success: function(json)
{
console.log("My country is: " + json.country);
},
error: function(err)
{
console.log("Request failed, error= " + err);
}
});

Webtechriser (点击这里阅读文章)(称为 Wipmania)提供免费且易于使用的服务。这是一个 JSONP服务,需要使用 超文本标示语言进行简单的 Javascript编码。它也可以在 JQuery中使用。我稍微修改了一下代码以改变输出格式,这就是我使用并发现正在工作的代码: (这是我的 HTML 页面的代码)

<html>
<body>
<p id="loc"></p>




<script type="text/javascript">
var a = document.getElementById("loc");


function jsonpCallback(data) {
a.innerHTML = "Latitude: " + data.latitude +
"<br/>Longitude: " + data.longitude +
"<br/>Country: " + data.address.country;
}
</script>
<script src="http://api.wipmania.com/jsonp?callback=jsonpCallback"
type="text/javascript"></script>




</body>
</html>

请注意: 这个服务获取访问者 没有的位置,提示访问者选择是否共享他们的位置,不像 HTML5地理定位 API(您编写的代码)。因此,隐私权受到了侵犯。所以,你应该司法地使用这项服务。

对于寻找功能齐全的地理定位实用程序的开发人员,您可以查看 地理定位器(我是作者)。

下面的示例将首先尝试 HTML5 Geolocation API 来获得确切的坐标。如果失败或被拒绝,它将回退到 Geo-IP 查找。一旦它得到了坐标,它会反向地理编码坐标到一个地址。

var options = {
enableHighAccuracy: true,
timeout: 6000,
maximumAge: 0,
desiredAccuracy: 30,
fallbackToIP: true, // if HTML5 geolocation fails or rejected
addressLookup: true, // get detailed address information
timezone: true,
map: "my-map" // this will even create a map for you
};


geolocator.locate(options, function (err, location) {
console.log(err || location);
});

它支持地理位置(通过 HTML5或 IP 查找) ,地理编码,地址查找(反座标化) ,距离和持续时间,时区信息和更多..。

你可以使用 (咒语)来获取访问者的位置,它支持 IPv6。

作为一个额外的好处,它允许检查 ip 地址是否是一个 tor 节点,公共代理或垃圾邮件发送者。

JavaScript 代码:

function getIPDetails() {
var ipAddress = document.getElementById("txtIP").value;


var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
console.log(JSON.parse(xhttp.responseText));
}
};
xhttp.open("GET", "http://ip-api.io/json/" + ipAddress, true);
xhttp.send();
}


<input type="text" id="txtIP" placeholder="Enter the ip address" />
<button onclick="getIPDetails()">Get IP Details</button>

JQuery 代码:

$(document).ready(function () {
$('#btnGetIpDetail').click(function () {
if ($('#txtIP').val() == '') {
alert('IP address is reqired');
return false;
}
$.getJSON("http://ip-api.io/json/" + $('#txtIP').val(),
function (result) {
alert('Country Name: ' + result.country_name)
console.log(result);
});
});
});


<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<div>
<input type="text" id="txtIP" />
<button id="btnGetIpDetail">Get Location of IP</button>
</div>

请参阅 Ipdata.co,这是我构建的一个快速且性能可靠的服务,因为它拥有10个全局端点,每个端点能够每秒处理超过10,000个请求!

这个答案使用了一个“ test”API Key,它非常有限,只能用于测试几个调用。注册为您自己的免费 API 密钥和获得多达1500个开发请求每天。

此代码片段将返回 目前 ip 的详细信息。要查找其他 ip 地址,只需将 ip 附加到 https://api.ipdata.co?api-key=test地址。

https://api.ipdata.co/1.1.1.1?api-key=test

API 还提供了一个 is_eu字段,指示用户是否在欧盟国家。

$.get("https://api.ipdata.co?api-key=test", function (response) {
$("#response").html(JSON.stringify(response, null, 4));
}, "jsonp");
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<pre id="response"></pre>

这是小提琴 https://jsfiddle.net/ipdata/6wtf0q4g/922/

我还写了 这个对8个最好的 IP 地理定位 API 的详细分析。

我想在不使用任何外部 API 的情况下为少数几个国家本地化客户端定价,所以我使用本地 Date 对象来获取这个国家 New Date ()) . toString () . split (’(’)[1] . split (“”)[0]

    document.write((new Date()).toString().split('(')[1].split(" ")[0])

Basically this small code snippet extracts the first word from Date object. To check for various time zone, you can change the time of your local machine.

In my case, our service only included three countries, so I was able to get the location using the following code.

const countries = ["India", "Australia", "Singapore"]
const countryTimeZoneCodes = {
"IND": 0,
"IST": 0,
"AUS": 1,
"AES": 1,
"ACS": 1,
"AWS": 1,
"SGT": 2,
"SIN": 2,
"SST": 2
} // Probable three characters from timezone part of Date object
let index = 0
try {
const codeToCheck = (new Date()).toString().split('(')[1].split(" ")[0].toUpperCase().substring(0, 3)
index = countryTimeZoneCodes[codeToCheck]


} catch (e) {


document.write(e)
index = 0
}


document.write(countries[index])

这只是为了提高用户体验。这不是一个完全可靠的解决方案来检测位置。为了防止检测不正确,我在菜单栏中添加了一个选择国家的下拉菜单。

如果你不想使用 api,只有国家对你来说是足够的,你可以使用 Topojson世界数据集

import { feature } from "https://cdn.skypack.dev/topojson@3.0.2";
import { geoContains, geoCentroid, geoDistance } from "https://cdn.skypack.dev/d3@7.0.0";


async function success(position) {
const topology = await fetch("https://cdn.jsdelivr.net/npm/world-atlas@2/countries-50m.json").then(response => response.json());
const geojson = feature(topology, topology.objects.countries);
    

const {
longitude,
latitude,
} = position.coords;
    

const location = geojson.features
.filter(d => geoContains(d, [longitude, latitude]))
.shift();
    

if (location) {
document.querySelector('#location').innerHTML = `You are in <u>${location.properties.name}</u>`;
}
    

if (!location) {
const closestCountry = geojson.features
// You could improve the distance calculation so that you get a more accurate result
.map(d => ({ ...d, distance: geoDistance(geoCentroid(d), [longitude, latitude]) }))
.sort((a, b) => a.distance - b.distance)
.splice(0, 5);
        

if (closestCountry.length > 0) {
const possibleLocations = closestCountry.map(d => d.properties.name);
const suggestLoctions = `${possibleLocations.slice(0, -1).join(', ')} or ${possibleLocations.slice(-1)}`;
            

document.querySelector('#location').innerHTML = `It's not clear where you are!<section>Looks like you are in ${suggestLoctions}</section>`;
}
        

if (closestCountry.length === 0) {
error();
}
}
}


function error() {
document.querySelector('#location').innerHTML = 'Sorry, I could not locate you';
};


navigator.geolocation.getCurrentPosition(success, error);

这段代码接受经纬度并检查这个点是否包含在 geojson 的一个特性中(一个空间有界的实体)。我还创建了一个工作 例子

你可以在不依赖 IP 服务的情况下自然地做到这一点,你可以得到用户的时区如下:

Intl.DateTimeFormat().resolvedOptions().timeZone

然后从该值中提取国家。 给你是 CodePen 的一个工作示例。

您可以简单地导入 app.component.ts或者您想要使用的任何组件

import { HttpClient } from '@angular/common/http';

然后向 http://ip-api.com/json发出一个简单的 GET请求

  getIPAddress() {
this.http.get("http://ip-api.com/json").subscribe((res: any) => {
console.log('res ', res);
})
}

通过使用它,您将得到以下响应:

{
"status": "success",
"country": "country fullname here",
"countryCode": "country shortname here",
"region": "region shortname here",
"regionName": "region fullname here",
"city": "city fullname here",
"zip": "zipcode will be in string",
"lat": "latitude here will be in integer",
"lon": "logitude here will be in integer",
"timezone": "timezone here",
"isp": "internet service provider name here",
"org": "internet service provider organization name here",
"as": "internet service provider name with some code here",
"query": "ip address here"
}