🌐 IP 归属地接口
接口根地址:https://ip.jwzcq.com/api/ip.php
0. 基础规范
请求方式
GET / POST (application/x-www-form-urlencoded / JSON)
CORS 跨域
已开启(Access-Control-Allow-Origin: *)
内容类型
application/json; charset=UTF-8
统一响应结构
// 成功
{
"code": 200,
"success": true,
"message": "success",
"data": { /* 业务数据结构 */ },
"timestamp": 1715000000
}
// 失败
{
"code": 400, // 400参数 404未找到 500服务器错
"success": false,
"message": "错误描述",
"data": null
}
API Key 鉴权
提示:
生产环境默认为所有查询接口开启 Key 校验(管理员可在后台「API 密钥管理」菜单中创建/管理密钥)。
ping 和 myip 两个 action 免密钥,用于监控和快速诊断。
| 传递方式 | 优先级 | 示例 |
HTTP Header: X-API-Key(推荐,日志不泄露) |
最高 |
X-API-Key: sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
POST body 参数 key | 中 | key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx |
GET 查询参数 key | 最低 | ?action=query&ip=8.8.8.8&key=sk_demo_xxxxx... |
1. 登录后台 → 「API 密钥管理」→「新增」创建密钥,sk_ 前缀的明文密钥只在创建成功时显示 一次,请立刻保存。
2. 密钥支持「每日调用配额」「IP 白名单(通配符 *)」「到期日」「启用/禁用」等策略。
3. 查询成功后,响应体 data._api_key 中包含该密钥的剩余配额信息(前端可用于限流提示)。
业务状态码说明
| code | 含义 | 说明 |
| 200 | 成功 | 请求正常响应,HTTP 200 |
| 400 | 参数错误 | 缺少参数 / IP 格式错误 / action 未知 |
| 401 | 密钥无效 | 未携带 key 或 key 不存在于数据库 |
| 403 | 密钥被禁 / 到期 / IP 不在白名单 | HTTP 状态码 403,详见 message 文本 |
| 404 | 未找到 | IP 格式合法但数据库中无匹配记录(found=false) |
| 405 | 方法不允许 | 批量查询仅支持 POST |
| 429 | 配额超限 | 今日调用次数已达 daily_quota 上限(每天 00:00 自动重置) |
| 500 | 服务端错误 | 数据库异常或其他运行时错误 |
HTTP 响应状态码
成功 / 业务失败
HTTP 200(通过 body.code 进一步判断)
鉴权类错误
HTTP 401 / 403 / 429(同时 body.code 也相同)
服务端错误
HTTP 500(body.code=500)
免 Key action
ping、myip(通过 ping 查看 auth_required 配置)
1. 单 IP 查询
查询指定 IPv4 地址的归属地信息(国家 / 省 / 市 / 区 / 运营商等,返回 IP 段、原始行、密钥配额)
接口地址
https://ip.jwzcq.com/api/ip.php
请求参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
| action | 否 | string | 默认值 query,可省略 | query |
| ip | 是 | string | 合法 IPv4 地址 | 8.8.8.8 |
| key | 生产必填 | string | API 密钥(也可通过 X-API-Key Header 传入,登录后台「API 密钥管理」创建) | sk_demo_xxxxx… |
调用示例
# GET(key 写在 URL,最快联调。key 需到后台「API 密钥管理」创建,此处为示例占位)
curl -X GET "https://ip.jwzcq.com/api/ip.php?action=query&ip=8.8.8.8&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# Header 传 key(生产推荐,不进日志)
curl -X GET "https://ip.jwzcq.com/api/ip.php?ip=8.8.8.8" \
-H "X-API-Key: sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# POST
curl -X POST "https://ip.jwzcq.com/api/ip.php" \
-d "action=query&ip=8.8.8.8&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# 浏览器 JS (fetch)
fetch("https://ip.jwzcq.com/api/ip.php?action=query&ip=8.8.8.8&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxx")
.then(r => r.json())
.then(json => console.log(json.data.location, json.data.full_location));
① 响应字段总览(外层 ApiResponse 结构)
| 字段 | 类型 | 说明 | 示例值 |
| code | int | HTTP 业务状态码(= HTTP 响应状态码) | 200 |
| success | bool | 是否成功,等价于 code === 200 | true |
| message | string | 可读描述,成功时固定 success | success |
| timestamp | int | 服务器响应时的 Unix 时间戳(秒) | 1786343022 |
| data | object|null | 业务查询结果,失败时为 null | 见下方 ② |
② data(业务查询结果)字段详解
| 字段 | 类型 | 说明 | 示例值 |
| success | bool | 查询是否成功(found=true 或 found=false 都算成功,参数错误/DB 异常为 false) | true |
| code | int | 业务级 code:200=查到或合法未查到 / 400=IP 非法 / 500=DB 异常 | 200 |
| message | string | 查询结果中文描述 | 查询成功 |
| ip | string | 查询的 IPv4 原始值 | 8.8.8.8 |
| ip_int | int | IP 对应的 32 位无符号整数(大端/网络字节序转换) | 134744072 |
| found | bool | 数据库中是否命中记录。未命中时其他 location 字段为空字符串 | true |
| start_ip / end_ip | string | 命中的 IP 段起 / 止(点分十进制,当段只有一个 IP 时两者相同) | 8.8.8.8 |
| start_ip_int / end_ip_int | string | 命中的 IP 段整数形式(字符串类型,避免 32 位 PHP int 溢出) | 134744072 |
| location | object | 标准化的归属地字段,前端 UI 直接使用 | 见 ③ |
| full_location | string | location 各字段用空格拼接的完整字符串(直接用于卡片展示) | 美国 加利福尼亚州 圣克拉拉 山景城 谷歌公司DNS服务器 |
| raw | object | 数据库表行的原始列集合(包含 id / 国家代码等扩展字段) | 见 ④ |
| query_time | string | 服务器执行查询的时间(Y-m-d H:i:s,按 SYS_TIMEZONE 时区) | 2026-08-10 14:23:42 |
| _api_key | object | (鉴权开启时附加)当前密钥的配额与元信息,用于前端限流提示 | 见 ⑤ |
③ data.location(归属地标准化字段)
| 字段 | 类型 | 对应原始列 | 示例值 |
| country | string | raw.country_name | 美国 |
| region | string | raw.region_name(省 / 州) | 加利福尼亚州 |
| city | string | raw.city_name(地级市) | 圣克拉拉 |
| county | string | raw.district_name(区 / 县 / 市下辖县级市) | 山景城 |
| isp | string | raw.isp_domain(运营商 / 组织) | 谷歌公司DNS服务器 |
| owner | string | raw.owner_domain(所有者/持有方,QQWry 通常留空) | "" |
| base_station | string | 基站信息(QQWry 通常留空;其他数据源扩展) | "" |
④ data.raw(数据库原始行,字段依 SQL 导入结果而定)
| 字段 | 类型 | 说明 | 示例值 |
| id | string | 数据库行自增主键(导出 CSV / 增量比对用) | 2403478 |
| start_ip / end_ip | string | 同 data.start_ip / end_ip | 8.8.8.8 |
| start_ip_int / end_ip_int | string | 同 data.start_ip_int / end_ip_int | 134744072 |
| country_name | string | 国家或地区(中文) | 美国 |
| region_name | string | 省 / 自治区 / 直辖市 / 州 | 加利福尼亚州 |
| city_name | string | 地级市 | 圣克拉拉 |
| district_name | string | 区 / 县 / 旗 / 县级市 | 山景城 |
| owner_domain | string | 持有单位 / 品牌 | "" |
| isp_domain | string | ISP 运营商 / DNS / CDN 标签 | 谷歌公司DNS服务器 |
| country_code | string | ISO 3166-1 alpha-2 两位国家代码(US/CN/…),QQWry 数据源可能为空 | US |
| continent_code | string | 大洲代码(NA / AS / EU / OC / AF / SA / AN) | NA |
⚠️ raw 中存在的列取决于 ip_data.sql 导入时 convert_ipdb_to_sql.py 从 .ipdb 元数据识别到的字段。
若某些列在导入 SQL 中不存在(如 country_code / continent_code),该列会缺失,请以 data.location 的标准字段作为主数据源。
⑤ data._api_key(鉴权开启时附加,密钥配额快照)
| 字段 | 类型 | 说明 | 示例值 |
| name | string | 密钥显示名称(后台设置) | IP查询 |
| owner | string | 密钥所属方 / 对接方负责人 | 博优科技 |
| daily_quota | int | 每日调用上限;0 代表不限量 | 0 |
| used_today | int | reset_day 当天累计的成功调用次数 | 28 |
| expires_at | string | 到期日期(Y-m-d);空字符串代表永久有效 | "" |
| reset_day | string | 配额重置锚点(服务器时区当天日期),00:00:00 后 used_today 自动清零 | 2026-08-10 |
完整响应示例(实际抓包结果)
{
"code": 200,
"success": true,
"message": "success",
"data": {
"success": true,
"code": 200,
"message": "查询成功",
"ip": "8.8.8.8",
"ip_int": 134744072,
"found": true,
"start_ip": "8.8.8.8",
"end_ip": "8.8.8.8",
"start_ip_int": "134744072",
"end_ip_int": "134744072",
"location": {
"country": "美国",
"region": "加利福尼亚州",
"city": "圣克拉拉",
"county": "山景城",
"isp": "谷歌公司DNS服务器",
"owner": "",
"base_station": ""
},
"full_location": "美国 加利福尼亚州 圣克拉拉 山景城 谷歌公司DNS服务器",
"raw": {
"id": "2403478",
"start_ip": "8.8.8.8",
"end_ip": "8.8.8.8",
"start_ip_int": "134744072",
"end_ip_int": "134744072",
"country_name": "美国",
"region_name": "加利福尼亚州",
"city_name": "圣克拉拉",
"district_name": "山景城",
"owner_domain": "",
"isp_domain": "谷歌公司DNS服务器",
"country_code": "US",
"continent_code": "NA"
},
"query_time": "2026-08-10 14:23:42",
"_api_key": {
"name": "IP查询",
"owner": "博优科技",
"daily_quota": 0,
"used_today": 28,
"expires_at": "",
"reset_day": "2026-08-10"
}
},
"timestamp": 1786343022
}
2. 批量 IP 查询
一次请求最多查询 100 个 IP,超出部分自动截断
接口地址
https://ip.jwzcq.com/api/ip.php
请求参数
| 参数 | 必填 | 类型 | 说明 |
| action | 是 | string | 必须为 batch |
| ips[] | 是 | array | 方式一:表单数组 ips[]=8.8.8.8&ips[]=114.114.114.114 |
| ips | string | 方式二:逗号分隔字符串 8.8.8.8,114.114.114.114 |
| JSON body | json | 方式三:Content-Type: application/json body: {"ips":["8.8.8.8"]} |
调用示例
curl -X POST "https://ip.jwzcq.com/api/ip.php?action=batch" \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "ips[]=8.8.8.8&ips[]=114.114.114.114&ips[]=1.1.1.1"
# 或者 JSON 方式
curl -X POST "https://ip.jwzcq.com/api/ip.php?action=batch" \
-H "Content-Type: application/json" \
-d '{"ips":"8.8.8.8,114.114.114.114"}'
3. 获取当前访问者 IP + 归属地
自动识别客户端真实 IP(兼容 CDN / 反向代理的 X-Forwarded-For 头)
接口地址
https://ip.jwzcq.com/api/ip.php
curl "https://ip.jwzcq.com/api/ip.php?action=myip"
4. 健康检查
用于监控服务器状态、数据库连通性及数据总数
接口地址
https://ip.jwzcq.com/api/ip.php
curl "https://ip.jwzcq.com/api/ip.php?action=ping"
// 返回示例
{ "code":200, "data": {
"status":"ok",
"db":"ok",
"count":3500000,
"version":"1.0.0",
"time":"2026-05-06 12:00:00"
} }
5. 各种语言调用示例
PHP (file_get_contents)
''
JavaScript (jQuery AJAX)
$.ajax({
url: "https://ip.jwzcq.com/api/ip.php",
type: "GET",
dataType: "json",
data: { action: "query", ip: "8.8.8.8" },
success: function(res) {
if (res.success && res.data.found) {
console.log(res.data.full_location);
}
}
});
Python (requests)
import requests
url = "https://ip.jwzcq.com/api/ip.php"
resp = requests.get(url, params={"action": "query", "ip": "8.8.8.8"})
data = resp.json()
if data["success"] and data["data"]["found"]:
print(data["data"]["full_location"])
📱 手机号归属地接口
接口根地址:https://ip.jwzcq.com/api/tel.php
· 基于 52 万+ 号段数据库,与 IP 接口共用同一套 API Key 鉴权。
T0. 接口概览
| 功能 | action | 方法 | 说明 |
| 单手机号查询 |
query |
GET / POST |
根据 11 位手机号 / 7 位号段 / 号段前缀返回归属地 |
| 批量查询(最多 100 个) |
batch |
POST |
一次请求批量查询多个手机号 |
| 健康检查(免 Key) |
ping |
GET |
检查数据库连接状态 + 返回号段总数 |
T1. 单手机号查询
根据手机号或号段前缀查询归属地信息。
URL
/api/tel.php?action=query
请求参数
| 参数 | 必填 | 类型 | 说明 | 示例 |
| action | 否 | string | 默认值 query,可省略 | query |
| tel | 是 | string | 11 位手机号 / 7 位号段 / 号段前缀(3~7 位),自动去空格、-、+86 前缀、全角数字 | 13800138000 |
| key | 可选 | string | API Key(也可用 Header: X-API-Key) | sk_demo_xxxxxxxxxxxxx |
调用示例
# GET + URL 参数
curl -X GET "https://ip.jwzcq.com/api/tel.php?action=query&tel=13800138000&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# POST + form body
curl -X POST "https://ip.jwzcq.com/api/tel.php" \
-H "X-API-Key: sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d "action=query&tel=13000001234"
# 前端 fetch
fetch("https://ip.jwzcq.com/api/tel.php?action=query&tel=13800138000&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxx")
.then(r => r.json())
.then(data => console.log(data))
成功响应示例
{
"code": 200,
"success": true,
"message": "success",
"data": {
"success": true,
"code": 200,
"message": "查询成功",
"tel": "13000001234",
"tel_length": 11,
"segment": "1300000",
"segment_int": 1300000,
"found": true,
"segment_range_start": "1300000",
"segment_range_end": "1300099",
"segment_count": 100,
"location": {
"country": "中国",
"region": "山东",
"city": "济南",
"county": "",
"isp": "中国联通"
},
"extra": {
"area_code": "0531",
"zip_code": "250000",
"district_code": "370100",
"code": "130"
},
"full_location": "中国 山东 济南 中国联通",
"query_time": "2026-08-11 14:23:42"
},
"timestamp": 1786419822
}
返回字段说明
| 字段路径 | 类型 | 说明 |
| data.tel | string | 标准化后的纯数字手机号(已去 +86、空格、- 等) |
| data.segment | string | 7 位号段(11 位手机号取前 7 位);仅输入 3-6 位前缀时可能为空 |
| data.found | bool | 是否在号段库中匹配到归属地 |
| data.location.country | string | 国家(固定"中国") |
| data.location.region | string | 省区,如 "山东" |
| data.location.city | string | 城市,如 "济南" |
| data.location.isp | string | 运营商:中国联通 / 中国移动 / 中国电信 等 |
| data.extra.area_code | string | 电话区号,如 "0531" |
| data.extra.zip_code | string | 邮政编码,如 "250000" |
| data.extra.district_code | string | 行政区划代码(6 位),如 "370100" |
| data.segment_range_start / end / count | string / int | 同运营商同城市的连续号段范围及号段个数(仅用于展示参考) |
| data.full_location | string | 完整归属地拼接(中国 省 市 运营商) |
T2. 批量查询
单次最多处理 100 个手机号,支持数组形式或逗号分隔形式提交。
URL
/api/tel.php?action=batch
单次最多
100 个手机号(超过自动截取前 100 个)
请求参数
| 参数 | 必填 | 类型 | 说明 |
| action | 是 | string | 必须为 batch |
| tels | 是 | string[] / string | 手机号数组 tels[]=13800138000&tels[]=13000001234 或逗号分隔字符串 tels=13800138000,13000001234,也支持 JSON body: {"tels":[...]} |
调用示例
# 数组形式(推荐)
curl -X POST "https://ip.jwzcq.com/api/tel.php?action=batch" \
-H "X-API-Key: sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d "tels[]=13800138000&tels[]=13000001234&tels[]=18912345678"
# 逗号分隔形式
curl -X POST "https://ip.jwzcq.com/api/tel.php?action=batch" \
-d "tels=13800138000,13000001234,15500000000"
T3. 健康检查(免 Key)
用于监控 / Nginx 健康检测 / 开机自检,无需 Key。
URL
/api/tel.php?action=ping
curl "https://ip.jwzcq.com/api/tel.php?action=ping"
// 返回
{
"code": 200,
"success": true,
"data": {
"status": "ok",
"db": "ok",
"table": "tel_location",
"count": 522410,
"time": "2026-08-11 14:30:00"
}
}
🗺️ 地图编码接口
接口根地址:https://ip.jwzcq.com/api/geo.php
· 基于天地图官方数据,后端代理方式调用,支持地理编码(地址→经纬度)与逆地理编码(经纬度→地址)。
与 IP / 手机号接口共用同一套 API Key 鉴权。
G0 接口概览
| 功能 | action | 方法 | 返回 | 说明 |
| 地理编码(地址→经纬度) |
geocode |
GET / POST |
JSON |
将结构化地址(省市区门址)解析为经纬度坐标,返回匹配级别与置信度 |
| 逆地理编码(经纬度→地址) |
reverse / revgeocode |
GET / POST |
JSON |
根据经纬度反查结构化地址、POI、道路、城市、区县及方位距离信息 |
| 🗺️ 地图标注嵌入 |
map / embed |
GET |
HTML |
支持地址自动定位/经纬度标注,可点击地图移动标注点、复制坐标,postMessage 双向通信,免 Key |
| 📍 坐标拾取嵌入 |
picker / pick |
GET |
HTML |
返回可 iframe 嵌入的交互式坐标拾取页面,点击地图获取坐标,支持 postMessage 回传,免 Key |
| 健康检查(免 Key) |
ping |
GET |
JSON |
检查天地图 Key 配置、Redis 缓存状态与版本信息 |
G1 地理编码(地址 → 经纬度)
将结构化地址(省市区+门址)解析为经纬度坐标,坐标系为天地图 CGCS2000。
URL
/api/geo.php?action=geocode
请求参数
| 参数 | 必填 | 类型 | 别名 | 说明 | 示例 |
| action | 否 | string | — | 默认值 geocode,可省略;别名 geo | geocode |
| address | 是 | string | addr / keyword | 结构化地址字符串,建议包含省市区 | 北京市海淀区莲花池西路28号 |
| key | 生产必填 | string | — | API Key(也可用 Header: X-API-Key) | sk_demo_xxxxx… |
调用示例
# GET(URL 参数)
curl -X GET "https://ip.jwzcq.com/api/geo.php?action=geocode&address=%E5%B9%BF%E5%B7%9E%E5%B8%82%E5%A4%A9%E6%B2%B3%E5%8C%BA%E7%8F%A0%E6%B1%9F%E6%96%B0%E5%9F%8E%E8%8A%B1%E5%9F%8E%E5%B9%BF%E5%9C%BA&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# POST + form body + Header 传 key(推荐)
curl -X POST "https://ip.jwzcq.com/api/geo.php" \
-H "X-API-Key: sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d "action=geocode&address=%E5%8C%97%E4%BA%AC%E5%B8%82%E6%B5%B7%E6%B7%80%E5%8C%BA%E8%8E%B2%E8%8A%B1%E6%B1%A0%E8%A5%BF%E8%B7%AF28%E5%8F%B7"
# 前端 fetch
fetch("https://ip.jwzcq.com/api/geo.php?action=geocode&address=%E4%B8%8A%E6%B5%B7%E5%B8%82%E6%B5%A6%E4%B8%9C%E6%96%B0%E5%8C%BA%E9%99%86%E5%AE%B6%E5%98%B4%E7%8E%AF%E8%B7%AF1000%E5%8F%B7&key=sk_demo_xxx")
.then(r => r.json())
.then(json => console.log(json.data.lon, json.data.lat))
成功响应示例
{
"code": 200,
"success": true,
"message": "success",
"type": "geocode",
"data": {
"address": "广州市天河区珠江新城花城广场",
"lon": 113.318470,
"lat": 23.123650,
"level": "兴趣点",
"score": 100
},
"query_time": "2026-08-20 15:30:54",
"timestamp": 1787209854
}
返回字段说明
| 字段路径 | 类型 | 说明 |
| data.address | string | 查询的原始地址(已 trim) |
| data.lon | float | 经度(CGCS2000 / WGS84 坐标系,保留 6 位小数) |
| data.lat | float | 纬度 |
| data.level | string | 匹配级别:如"兴趣点"、"道路"、"门址"、"行政区划"等 |
| data.score | int | 匹配置信度(0~100),分值越高越精确 |
| type | string | 固定 geocode |
G2 逆地理编码(经纬度 → 地址)
根据经纬度坐标反查结构化地址、POI、道路、城市、区县及最近 POI 方位距离等信息。
URL
/api/geo.php?action=reverse
action 别名
revgeocode / regeo
请求参数
| 参数 | 必填 | 类型 | 别名 | 说明 | 示例 |
| action | 是 | string | — | 必须为 reverse(或 revgeocode/regeo) | reverse |
| lon | 是 | float | lng / longitude / x | 经度,范围 -180~180 | 116.397428 |
| lat | 是 | float | latitude / y | 纬度,范围 -90~90 | 39.90923 |
| key | 可选 | string | — | API Key(推荐 Header 方式) | sk_demo_xxxxx… |
调用示例
# GET(天安门坐标)
curl -X GET "https://ip.jwzcq.com/api/geo.php?action=reverse&lon=116.397428&lat=39.90923&key=sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
# POST(别名 revgeocode)
curl -X POST "https://ip.jwzcq.com/api/geo.php" \
-H "X-API-Key: sk_demo_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-d "action=revgeocode&lon=113.318470&lat=23.123650"
成功响应示例
{
"code": 200,
"success": true,
"message": "success",
"type": "reversegeocode",
"data": {
"lon": 116.397428,
"lat": 39.909230,
"formatted_address": "北京市东城区东华门街道天安门",
"city": "北京市",
"address": "天安门",
"road": "东长安街",
"poi": "天安门广场",
"poi_distance": 120,
"poi_position": "东北"
},
"query_time": "2026-08-20 15:32:00",
"timestamp": 1787209920
}
返回字段说明
| 字段路径 | 类型 | 说明 |
| data.lon / lat | float | 查询时传入的经纬度(已格式化) |
| data.formatted_address | string | 完整的规范化地址字符串 |
| data.city | string | 所在城市 / 直辖市 |
| data.address | string | 最近的地点名称(如 POI / 门址 / 地标) |
| data.road | string | 最近道路名称 |
| data.poi | string | 最近的 POI(兴趣点)名称 |
| data.poi_distance | int | 距离最近 POI 的直线距离(米) |
| data.poi_position | string | 最近 POI 相对于查询点的方位(如"东北"、"正南") |
| type | string | 固定 reversegeocode |
G3 健康检查(免 Key)
用于监控 / 开机自检,检查天地图 Key 配置状态、Redis 缓存连接情况及版本信息,无需 API Key。
URL
/api/geo.php?action=ping
curl "https://ip.jwzcq.com/api/geo.php?action=ping"
// 返回
{
"code": 200,
"success": true,
"message": "pong",
"data": {
"status": "ok",
"version": "1.0.0",
"tk_configured":true,
"redis": true,
"redis_stats": { /* 命中/未命中统计 */ },
"time": "2026-08-20 15:35:00",
"timestamp": 1787210100
}
}
G4 🗺️ 地图标注嵌入页(iframe)免 Key
返回一个可直接嵌入 iframe 的完整 HTML 地图页面。支持传入地址自动地理编码定位,也支持传入经纬度直接标注。
地图标注点可点击拖动调整位置,内置坐标复制、信息窗展示、postMessage 双向通信等功能,适合后台管理面板、表单详情页、位置展示等场景,无需自行对接天地图 JS API。
URL
/api/geo.php?action=map
请求参数
| 参数 | 必填 | 类型 | 默认值 | 说明 |
| address |
二选一 |
string |
— |
地址参数(推荐):传入文本地址,服务端自动调用天地图地理编码解析为经纬度后标注。若同时传了 lon/lat 则优先使用经纬度 |
| lon + lat |
float |
116.397 / 39.909 |
坐标参数:直接指定标注点经纬度(别名 lng/x 和 y) |
| zoom | 否 | int | 15(地址模式16) | 地图初始缩放级别(3~18,越大越精细) |
| title | 否 | string | 标注位置 / 地址文本 | 信息窗标题文字 |
| content | 否 | string | 经纬度数值 / 地址文本 | 信息窗正文(地址模式下默认显示传入的地址);注意:若未传 address 且未传 lon/lat,content 会被当作地址尝试解析 |
| pickable | 否 | bool | true | 是否允许点击地图移动标注点,传 0 或 false 禁用 |
| marker | 否 | string | red | 预留标记颜色参数 |
📌 在线调用实例(点击即可体验)
以下链接可直接在浏览器中打开体验,蓝色按钮为地址定位(自动解析),灰色按钮为经纬度直接标注(免 Key):
📍 地址模式 URL:https://ip.jwzcq.com/api/geo.php?action=map&address=重庆市两江新区洋河路9号
📍 坐标模式 URL:https://ip.jwzcq.com/api/geo.php?action=map&lon=116.397&lat=39.909&zoom=16
嵌入示例
<!-- ① 地址模式:只需传 address,自动地理编码(推荐)-->
<iframe
src="https://ip.jwzcq.com/api/geo.php?action=map&address=%E9%87%8D%E5%BA%86%E5%B8%82%E4%B8%A4%E6%B1%9F%E6%96%B0%E5%8C%BA%E6%B4%8B%E6%B2%B3%E8%B7%AF9%E5%8F%B7&title=公司地址"
width="100%" height="450"
frameborder="0" allowfullscreen
style="border-radius:12px; box-shadow:0 2px 12px rgba(0,0,0,.08);">
</iframe>
<!-- ② 坐标模式:直接指定经纬度 -->
<iframe id="mapFrame" width="600" height="400" frameborder="0"></iframe>
// JS 动态加载(地址模式)
function showAddressMap(address, title) {
var url = "https://ip.jwzcq.com/api/geo.php?action=map"
+ "&address=" + encodeURIComponent(address)
+ "&title=" + encodeURIComponent(title || "标注位置");
document.getElementById("mapFrame").src = url;
}
// 调用:showAddressMap("重庆市两江新区洋河路9号", "公司地址");
postMessage 双向通信
嵌入页面后,父窗口可通过 postMessage 与地图交互:
① 子页面 → 父页面(坐标变化通知)
地图加载完成和用户点击移动标注后,iframe 会向父窗口发送消息:
// 父页面监听坐标变化
window.addEventListener("message", function(e) {
if (e.data && e.data.type === "geo_mark") {
console.log("标注坐标:", e.data.lon, e.data.lat);
// e.data.lon = 经度(Number)
// e.data.lat = 纬度(Number)
// e.data.coord = "lon,lat" 字符串
// e.data.address = 原始地址(地址模式下有值)
}
});
② 父页面 → 子页面(远程设置标注点)
父页面可发送消息远程更新标注点位置(无需刷新 iframe):
var frame = document.getElementById("mapFrame");
// 动态更新标注点到上海东方明珠
frame.contentWindow.postMessage({
type: "geo_set_marker",
lon: 121.499809,
lat: 31.239666,
zoom: 16 // 可选
}, "*");
页面功能特性
- 🆕 地址自动定位:传入 address 或 content 参数,服务端自动调用天地图地理编码,无需前端转换
- 🆕 点击移动标注:默认开启(pickable=true),点击地图任意位置即可移动标注点,实时更新信息窗和坐标
- 天地图矢量底图 + 中文注记,全屏铺满 iframe,支持滚轮缩放 / 拖拽 / 双击放大
- 信息窗内置"📋 复制坐标"和"🎯 居中"按钮,一键复制当前标注坐标到剪贴板
- 右上角半透明毛玻璃坐标栏,实时显示当前标注点经纬度
- 地址解析失败时显示友好错误页面(不会白屏)
- postMessage 双向通信:子页面通知坐标变化,父页面可远程设置标注点
- 左上角蓝色提示条(点击移动标注时自动消失),顶部 Toast 通知交互反馈
- 响应式自适应 iframe 尺寸,移动端可正常使用
- 传
pickable=0 可禁用点击移动,变为纯展示模式
G5 📍 坐标拾取嵌入页(iframe)免 Key
返回一个可嵌入 iframe 的交互式地图页面,用户可以在地图上点击任意位置拾取坐标。支持 postMessage 实时回传坐标、callback URL 跳转回传、一键复制坐标等功能,非常适合表单中的"地图选点"场景。
URL
/api/geo.php?action=picker
请求参数
| 参数 | 必填 | 类型 | 默认值 | 说明 |
| lon | 否 | float | 116.397428 | 地图初始中心点经度(别名 lng / x) |
| lat | 否 | float | 39.90923 | 地图初始中心点纬度(别名 y) |
| zoom | 否 | int | 12 | 初始缩放级别(3~18) |
| callback | 否 | string | — | 确认坐标后跳转的回调 URL,坐标将以 ?lon=xxx&lat=xxx 形式附加 |
| lon_field | 否 | string | lon | 回传时经度的参数名 |
| lat_field | 否 | string | lat | 回传时纬度的参数名 |
📌 在线调用实例(点击即可体验)
以下链接可直接在浏览器中打开,体验坐标拾取功能(免 Key,点击地图任意位置取点):
示例 URL:https://ip.jwzcq.com/api/geo.php?action=picker&lon=116.397&lat=39.909&zoom=14
💡 操作提示:打开后鼠标移动实时显示坐标 → 点击地图放置标记 → 点击信息窗内"复制"或底部"确认坐标"按钮即可获取坐标。
坐标回传方式
拾取页支持两种方式将坐标传回父页面,可同时使用:
① postMessage(推荐,适合 iframe 嵌入场景)
用户在地图上点击拾取坐标或点击"✅ 确认坐标"按钮后,iframe 会向父窗口发送 postMessage:
// 父页面监听坐标回传
window.addEventListener("message", function(e) {
if (e.data && e.data.type === "geo_pick") {
console.log("拾取坐标:", e.data.lon, e.data.lat, e.data.coord);
// e.data.lon = 经度(Number)
// e.data.lat = 纬度(Number)
// e.data.coord = "lon,lat" 字符串(6位小数)
document.getElementById("lonInput").value = e.data.lon.toFixed(6);
document.getElementById("latInput").value = e.data.lat.toFixed(6);
}
});
② Callback URL 跳转(适合弹窗 / 新窗口场景)
传入 callback 参数后,用户点击"确认"会跳转到该 URL 并将坐标作为 query 参数附加:
<!-- 传入 callback,确认后跳回表单页 -->
<iframe src="https://ip.jwzcq.com/api/geo.php?action=picker&lon=113.318&lat=23.123&callback=https%3A%2F%2Fip.jwzcq.com/geo_form.php&lon_field=lng&lat_field=lat"
width="800" height="500" frameborder="0">
</iframe>
// 确认后跳转至:https://ip.jwzcq.com/geo_form.php?lng=113.318470&lat=23.123650
页面交互说明
- 鼠标在地图上移动时,底部坐标栏实时显示当前位置经纬度
- 点击地图任意位置:放置红色标记,弹出信息窗显示坐标,"确认坐标"按钮出现
- 信息窗内"📋 复制"按钮:一键复制坐标(格式
lon,lat)到剪贴板
- 信息窗内"✅ 确认"按钮:触发 postMessage + callback 跳转
- 底部"✅ 确认坐标"按钮:与信息窗确认按钮功能相同
- 支持滚轮缩放、拖拽平移、双击放大
- X-Frame-Options: SAMEORIGIN,仅允许同源嵌入;如需跨域嵌入可通过反向代理
完整集成示例
<!-- HTML:表单中嵌入坐标拾取 -->
<div class="form-row">
<label>经度:<input type="text" id="formLon" readonly></label>
<label>纬度:<input type="text" id="formLat" readonly></label>
<button type="button" onclick="openPicker()">📍 地图选点</button>
</div>
<iframe id="pickerFrame" style="display:none;width:100%;height:450px;border:1px solid #ddd;border-radius:8px;"></iframe>
<script>
function openPicker() {
var lon = document.getElementById("formLon").value || 116.397;
var lat = document.getElementById("formLat").value || 39.909;
var f = document.getElementById("pickerFrame");
f.src = "https://ip.jwzcq.com/api/geo.php?action=picker&zoom=14&lon="+lon+"&lat="+lat;
f.style.display = "block";
}
window.addEventListener("message", function(e) {
if (e.data && e.data.type === "geo_pick") {
document.getElementById("formLon").value = e.data.lon.toFixed(6);
document.getElementById("formLat").value = e.data.lat.toFixed(6);
document.getElementById("pickerFrame").style.display = "none";
}
});
</script>