前端页面获取访问者的IP地址经纬度和地理位置

Posted Love丶伊卡洛斯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前端页面获取访问者的IP地址经纬度和地理位置相关的知识,希望对你有一定的参考价值。

前言

本文主要通过高德地图API进行一系列的分析。提供具体的讲解和源码。
获取的经纬度和地理位置精确度并不高,仅供参考
请勿非法使用,本人概不负责。
临时测试页面:传送门
效果如下

前期准备

注册成为开发者,获取Key

高德开发平台:https://console.amap.com/dev/key/app
注册用户
填写相关信息成为开发者

创建key

需要先创建应用


然后点击添加

选择“web服务”,我们需要的就是 逆地理编码 和 IP定位API。ps:点击服务的蓝色字可以跳转到官方教程

创建完成后,就能获取到key了

IP定位和逆地理编码API文档

https://lbs.amap.com/api/webservice/guide/api/ipconfig/

https://lbs.amap.com/api/webservice/guide/api/georegeo/

思路讲解

1、IP地址获取

采用2种方式,如果本地运行,选用搜狐接口 http://pv.sohu.com/cityjson?ie=utf-8,可以获取到访问者IP等信息。如果有web服务器,可以采用自建http请求获取访问者IP。

2、IP定位获取经纬度

调用高德地图 IP定位API https://restapi.amap.com/v5/ip?type=4&key=<用户的key>&ip=114.247.50.2
注意,上面的key就是我们刚才申请的应用里的key,将其替换于此,type是IP类型,ip就是你要查的IP。

我这用postman测试下,我们要的就是location,返回的json数据方便解析

3、逆地理编码获取地理位置

调用高德地图 逆地理API https://restapi.amap.com/v3/geocode/regeo?location=116.310003,39.991957&key=<用户的key>&radius=1000&extensions=all
其中location就是我们上一步获取的经纬度信息,key就是我们申请的key,其他参数都是调节用的,因为这些数据不确定,所以我实现时进行了简化。

测试,简化后,我们就获取formatted_address的内容

代码实现

本地运行版

创建XMLHttpRequest对象的实现并不严谨,可以优化,不过我懒了0.0
XMLHttpRequest - Web API 接口参考 | MDN
XMLHttpRequest 对象 W3C

文件名为 ip_pos.html,后缀是html就行

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <title>
        我找到你了
    </title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>
    <span id="ip"></span>
    <br>
    <span id="pos"></span>
    <br>
    <span id="address"></span>
</body>
<script src="http://pv.sohu.com/cityjson?ie=utf-8"></script>
<script type="text/javascript">
    // 存储IP地址
    var ip = returnCitySN["cip"];
    document.getElementById("ip").innerText = "你的IP是" + ip;
    get_pos(ip);

    function get_pos(ip)
    {
        // 构建url
        var url = "https://restapi.amap.com/v5/ip?key=<你的key>&type=4&ip=" + ip;
        // 建立所需的对象
        var httpRequest = new XMLHttpRequest();
        // 打开连接  将请求参数写在url中 
        httpRequest.open('GET', url, true);
        // 发送请求  将请求参数写在URL中
        httpRequest.send();
        // 经纬度坐标
        var pos = "";
        // 获取数据后的处理程序
        httpRequest.onreadystatechange = function () {
            if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                // 获取到json字符串
                var ret = httpRequest.responseText;
                //console.log(ret);
                // 转为JSON对象
                var json = JSON.parse(ret);
                console.log(json);
                pos = json["location"];
                document.getElementById("pos").innerText = "你的经纬度是" + pos;

                get_addr(pos);
            }
        };
    }
    
    function get_addr(pos)
    {
        var httpRequest = new XMLHttpRequest();
        url = "https://restapi.amap.com/v3/geocode/regeo?key=<你的key>&radius=0&extensions=all&batch=false&location=" + pos;
        httpRequest.open('GET', url, true);
        httpRequest.send();
        httpRequest.onreadystatechange = function () {
            if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                // 获取到json字符串
                var ret = httpRequest.responseText;
                //console.log(ret);
                // 转为JSON对象
                var json = JSON.parse(ret);
                console.log(json);
                var address = json["regeocode"]["formatted_address"];
                console.log(address);
                document.getElementById("address").innerText = "你的地址大概是" + address;
                
            }
        };
    }
</script>

</html>

web服务版

我这里用的CGI,web服务为boa或apache。

ip_pos.html

<!DOCTYPE html>
<html lang="zh-CN">

<head>
    <title>
        我找到你了
    </title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>

<body>
    <span id="ip"></span>
    <br>
    <span id="pos"></span>
    <br>
    <span id="address"></span>
</body>

<script type="text/javascript">
    // 存储IP地址
    var ip = "";
    var xmlhttp;
	if(window.XMLHttpRequest)
	{
		//code for IE7+,Firefox,Chrome,Opera,Safari
		xmlhttp = new XMLHttpRequest();
	}
	else
	{
		//code for IE6,IE5
		xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
	}
	xmlhttp.onreadystatechange = function()
	{
		if(xmlhttp.readyState == 4)
		{
			if(xmlhttp.status == 200)
			{
				//将接收到的字符串存入str
				var str = xmlhttp.responseText;
				if(str.length == 0)
				{
					return;
				}
				
				// 解决XML, 解析错误:语法错误
				try //Internet Explorer
				{
					xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
					xmlDoc.async = "false";
					xmlDoc.loadXML(text);
				} catch (e) {
					try //Firefox, Mozilla, Opera, etc.
					{
						parser = new DOMParser();
						xmlDoc = parser.parseFromString(str, "text/xml");
					} catch (e) { alert(e.message) }
				}

				var ret = xmlDoc.getElementsByTagName('p')[0].textContent;
				ip = ret;
                console.log(ip);
                document.getElementById("ip").innerText = "你的IP是" + ip;

                get_pos(ip);
			}
			else
			{
				//alert(xmlhttp.status);
			}

		}
		else
		{
			//alert(xmlhttp.readyState);
		}
	}
	
	xmlhttp.open("GET","cgi-bin/get_ip.cgi?get",true);
	xmlhttp.send();

    function get_pos(ip)
    {
        // 构建url
        var url = "https://restapi.amap.com/v5/ip?key=<你的key>&type=4&ip=" + ip;
        // 建立所需的对象
        var httpRequest = new XMLHttpRequest();
        // 打开连接  将请求参数写在url中 
        httpRequest.open('GET', url, true);
        // 发送请求  将请求参数写在URL中
        httpRequest.send();
        // 经纬度坐标
        var pos = "";
        // 获取数据后的处理程序
        httpRequest.onreadystatechange = function () {
            if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                // 获取到json字符串
                var ret = httpRequest.responseText;
                //console.log(ret);
                // 转为JSON对象
                var json = JSON.parse(ret);
                console.log(json);
                pos = json["location"];
                document.getElementById("pos").innerText = "你的经纬度是" + pos;

                get_addr(pos);
            }
        };
    }
    
    function get_addr(pos)
    {
        var httpRequest = new XMLHttpRequest();
        url = "https://restapi.amap.com/v3/geocode/regeo?key=<你的key>&radius=0&extensions=all&batch=false&location=" + pos;
        httpRequest.open('GET', url, true);
        httpRequest.send();
        httpRequest.onreadystatechange = function () {
            if (httpRequest.readyState == 4 && httpRequest.status == 200) {
                // 获取到json字符串
                var ret = httpRequest.responseText;
                //console.log(ret);
                // 转为JSON对象
                var json = JSON.parse(ret);
                console.log(json);
                var address = json["regeocode"]["formatted_address"];
                console.log(address);
                document.getElementById("address").innerText = "你的地址大概是" + address;
                
            }
        };
    }
</script>

</html>

get_ip.c

配合 cgic.h 和 cgic.c编译 gcc get_ip.c cgic.c -o get_ip.cgi

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "cgic.h"

int cgiMain(void)
{
        // 用于接收环境变量QUERY_STRING
        char *lenstr = NULL;

        // 搜索环境变量 QUERY_STRING,并返回相关的值给字符串lenster。
        lenstr = getenv("QUERY_STRING");
        // 若没有找到环境变量 QUERY_STRING,直接return
        if (lenstr == NULL)
        {
                return -1;
        }

        // 使用MIME头信息″Content-type: text/html\\n\\n″来输出HTML源代码给Web服务器。
        // 请注意任何MIME头信息后必须有一个空行。一旦发送这个MIME头信息给Web服务器后,Web浏览器将认为随后的文本输出为HTML源代码
        printf("Content-type: text/html\\n\\n");

        printf("<p>%s</p>", cgiRemoteAddr);
        return 0;
}

以上是关于前端页面获取访问者的IP地址经纬度和地理位置的主要内容,如果未能解决你的问题,请参考以下文章

php的 ip 定位,经纬度至少精确到镇,附上源码和详解

java类中怎么根据经纬度获取地址

从IP地址获取地理位置[重复]

如何通过IP地址或精确定位获取用户的经纬度

用于从 IP 地址获取地理编码的 Java 库

百度地图用ip获取当前位置的经纬度(高精度)