API v1.0.0
开发接口文档
基于 HTTP/JSON 的标准接口,支持跨域 CORS,支持 GET / POST。
所有接口地址: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)
'
Warning: file_get_contents(<?php echo htmlspecialchars($baseUrl); ?>/api/ip.php?ip=8.8.8.8): failed to open stream: No such file or directory in /disk/webroot/ip.jwzcq.com/api_docs.php on line 409
Notice: Trying to access array offset on value of type null in /disk/webroot/ip.jwzcq.com/api_docs.php on line 411
'
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"])