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

18 篇文章 3 订阅
8 篇文章 0 订阅

前言

本文主要通过高德地图API进行一系列的分析。提供具体的讲解和源码。
获取的经纬度和地理位置精确度并不高,仅供参考
请勿非法使用,本人概不负责。
效果如下
在这里插入图片描述

前期准备

注册成为开发者,获取Key

高德开发平台:https://console.amap.com/dev/key/app
注册用户
填写相关信息成为开发者
在这里插入图片描述
创建key
在这里插入图片描述
需要先创建应用
在这里插入图片描述
在这里插入图片描述
然后点击添加
在这里插入图片描述
选择“web服务”,我们需要的就是 逆地理编码 和 IP定位API。ps:点击服务的蓝色字可以跳转到官方教程
在这里插入图片描述
创建完成后,就能获取到key了
在这里插入图片描述

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

2022/07/22 发现v5已经改v3了,注意适配 https://restapi.amap.com/v3/ip?ip=114.247.50.2&output=xml&key=<用户的key>
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/v3/ip?key=<你的key>&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["rectangle"];
                document.getElementById("pos").innerText = "你的经纬度是" + pos;
				
				pos_arr = pos.split(';');
				
                get_addr(pos_arr[0]);
            }
        };
    }
    
    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>


旧版本(已不适用)

<!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;
}

评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Love丶伊卡洛斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值