【问题标题】:How to get visitor's location (i.e. country) using geolocation?如何使用地理位置获取访问者的位置(即国家/地区)?
【发布时间】:2011-03-30 04:50:54
【问题描述】:

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

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

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

到目前为止,我能找到的只是显示谷歌地图界面的功能,但实际上没有一个能提供我想要的功能,除了 this library 工作良好 in this example 但由于某种原因在我的计算机。我不知道为什么那里出错了。

不管怎样,你知道我如何简单地返回一个数组,其中包含来自纬度和经度值的国家、城市等信息吗?

【问题讨论】:

  • $.get("https://api.ipdata.co", function (response) { $("#response").html(JSON.stringify(response, null, 4)); }, "jsonp");
  • 见小提琴jsfiddle.net/6wtf0q4g
  • 快速免责声明,我构建了上述服务 ipdata.co,它还具有极强的可扩展性,有 10 个全球端点,每个端点每天能够处理超过 8 亿次调用!
  • @SamuelLiew 我不相信这种情况下的副本是有效的。这个问题专门询问地理位置,而重复询问的是语言环境,这是一个类似但不同的问题(因为语言环境不包括纬度和经度、城市等)。

标签: javascript geolocation


【解决方案1】:

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

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

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

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

【讨论】:

  • 这对我不起作用,当我请求数据时,我会得到完整的网站作为我的响应。有没有更好的服务可以打电话?
  • 您可以通过将 /json 添加到 url 来强制 json 响应。你提出的要求是什么?它应该会自动检测到你想要 json。
  • 但它不支持带有“https”的站点。太可惜了。
  • 请注意,从定价页面: > 如果您需要每天向我们的 API 发出少于 1,000 个请求并且它是用于非商业用途,或者您只是想测试一下,请免费注册计划。否则,请选择以下付费计划之一。 - ipinfo.io/pricing
  • 你不是在回答技术问题,而是在为你的公司做广告,wtf?每个 SO 问题都可以这样回答。 :“打电话给我们并与我们的顾问交谈”
【解决方案2】:

如果您只需要用户所在的国家/地区,则无需定位用户。您可以在任何 IP-to-location 服务(如 maxmindipregistryip2location)中查找他们的 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);
    });

如果你真的需要获取他们的位置,你可以通过该方法获取他们的纬度/经度,然后查询Google'sYahoo's反向地理编码服务。

【讨论】:

  • @juanpastas 你没有。你只要ping一个服务,服务就会知道。或者您自己编写服务,但这超出了纯 javascript 范围。
  • 但是要 ping 一个服务,那会在服务器端吗?你知道客户的方法吗?
  • 如果我通过不同国家的代理访问互联网怎么办?
  • ipregistry.co 比其他选择更慷慨。它有一个免费的 100k API 调用层,注册很简单,不需要输入信用卡。
  • 不错的推荐,我试过 ipregistry,信息很简单。
【解决方案3】:

您可以使用您的 IP 地址来获取您的“国家”、“城市”、“isp”等...
只需使用为您提供简单 api 的 Web 服务之一,例如 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);
  }
});

【讨论】:

  • 由于 ip-api.com 不支持 https 请求,如果从 https 内容/页面中调用,大多数浏览器将拒绝该请求。另外,根据他们的网站,> 您可以免费将 ip-api.com 用于非商业用途。未经事先批准,我们不允许用于商业用途。
  • ip-api 只是提供 IP-Location 服务的不同服务的一个示例。该问题不涉及https 协议。如果您确实使用https 网站,我相信您可以实现相同的逻辑,只是使用不同的 IP-Location 服务。
【解决方案4】:

请参阅 ipdata.co 我构建的一项服务,该服务速度快且性能可靠,这要归功于拥有 10 个全局端点,每个端点能够每秒处理超过 10,000 个请求!

此答案使用非常有限的“测试”API 密钥,仅用于测试少数调用。 Signup 获取您自己的免费 API 密钥,每天最多可收到 1500 个开发请求。

这个 sn-p 将返回您的 当前 ip 的详细信息。要查找其他 ip 地址,只需将 ip 附加到 https://api.ipdata.co?api-key=test url 例如。

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/

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

【讨论】:

  • 那是错误的。该服务每月最多可免费处理 45,000 个请求。最小的计划是 10 美元,并返回提到的错误以防止滥用。请注意,它还附有一封电子邮件,警告您已用尽所有请求。
  • 我的评论不假
  • 您的评论本质上是虚假和误导性的。
【解决方案5】:

您无法通过 ip 获取城市位置。 在这里您可以使用 jquery 获取国家/地区:

$.get("http://ip-api.com/json", function(response) {
console.log(response.country);}, "jsonp");

【讨论】:

  • 其他人在你之前给出了这个答案 + 他们补充说如果你的服务器在 https 服务器上运行,这将不起作用。网络浏览器将阻止它,因为它是一个不安全的调用。
【解决方案6】:

ws.geonames.org 提供了一个非常易于使用的服务。这是一个示例网址:

http://ws.geonames.org/countryCode?lat=43.7534932&amp;lng=28.5743187&amp;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);
        });
    });
}​

Try it on jsfiddle.net ...

【讨论】:

【解决方案7】:

Webtechriser (click here to read the article)(称为wipmania)提供免费且易于使用的服务。这是一项 JSONP 服务,需要使用 HTML 进行简单的 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>

请注意:HTML 5 geolocation API(您编写的代码)。因此,隐私受到损害。因此,您应该对这项服务进行司法使用。

【讨论】:

  • 我看到 0 代表 LatitudeLongitudeUnknown 代表 Country 堆栈溢出但当我在 HTML 网页中使用它时它起作用了。
  • 我刚刚在我的一个非常古老的网站上使用了它,我很高兴地说它可以工作:e-artlab.com/about-you - 虽然不是在所有平台或浏览器上(在我合作伙伴的 Win/Edge 和Win/Chrome 访问被阻止,尽管我的 Mac/Chrome 很好)?
  • 使用 HTTP 的不安全连接。
【解决方案8】:

我想在不使用任何外部 API 的情况下本地化少数国家/地区的客户端定价,因此我使用本地 Date 对象来获取国家/地区 new Date()).toString().split('(')[1].split(" ")[0]

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

基本上这个小代码 sn-p 从 Date 对象中提取第一个单词。要检查不同的时区,您可以更改本地机器的时间。

就我而言,我们的服务只包括三个国家,所以我可以使用以下代码获取位置。

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])

这只是为了改善用户体验。这不是检测位置的完整证明解决方案。作为未正确检测的后备方案,我在菜单栏中添加了一个下拉菜单以选择国家/地区。

【讨论】:

  • 这只是为了改善用户体验,为了让新用户从下拉列表中选择国家,我们可以为少数提供自动选择。对于您的东部地区,您要么来自美国,要么来自加拿大。参考en.wikipedia.org/wiki/Eastern_Time_Zone
【解决方案9】:

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

下面的示例将首先尝试 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 查找)、地理编码、地址查找(反向地理编码)、距离和持续时间、时区信息等等...

【讨论】:

  • 就像一个魅力!但是,您需要在 google 上启用多个 API 才能使其正常工作。必须启用 Google Maps Time Zone APIGoogle Maps Geocoding API。将其添加到文档中可以为用户节省更多时间:)。谢谢!
  • Geolocator 在这里有详细的文档:onury.github.io/geolocator/?api=geolocator 谢谢。
【解决方案10】:

您可以使用ip-api.io 获取访问者的位置。它支持 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>

【讨论】:

  • 最好在直接的 JavaScript 中也包含一个示例,任何使用 JQuery 的人 :-)
  • 感谢@DaveEveritt!我也添加了 JavaScript 代码。
  • 其他人在您之前给出了这个答案 + 它不适用于 HTTPS 网站,因为您的网络浏览器不允许调用 http://...,因为它们不安全。
【解决方案11】:

如果你不想使用 api 并且只有国家就足够了,你可以使用 topojsonworldatlas

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 的一个特征(空间有界实体)中。我还创建了一个有效的example

【讨论】:

    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-26
    • 2011-01-28
    • 1970-01-01
    相关资源
    最近更新 更多