用libcurl发起HTTP请求获取IP地理信息需四步:安装libcurl并启用SSL支持,构造带User-Agent头的GET请求至ipapi.co等API,用nlohmann::json解析JSON响应,严格校验HTTP返回码、响应非空及JSON结构有效性后再提取country_name等字段。

用 libcurl 发起 HTTP 请求获取 IP 地理信息
纯 C++ 标准库不提供网络请求能力,必须借助第三方库。最轻量、跨平台且易集成的是 libcurl。它能发 GET 请求到公开的 IP 查询 API(如 ipapi.co、ipinfo.io 或 ip-api.com),拿到 JSON 响应后解析即可。
注意:不要自己实现 HTTP 协议或用原始 socket 拼 HTTP 报文——出错率高、编码/重定向/SSL 验证等细节极易遗漏。
- 推荐用
ipapi.co/v1/ip/(免费版限 1000 次/天,返回字段全,含country_name、region_name、city、latitude、longitude) - 请求时加
User-Agent头,否则部分服务会拒绝(如ip-api.com对无 UA 的请求返回403) - 务必启用 SSL 支持(编译时链接
-lcurl -lssl -lcrypto,Windows 下需额外配置 OpenSSL DLL 路径)
用 nlohmann::json 解析响应体
libcurl 只负责拿回一串字符串,地理信息藏在 JSON 里,得靠 JSON 库提取。C++ 没有标准 JSON 解析器,nlohmann::json 是事实标准:头文件仅需 #include <nlohmann/json.hpp>,无需编译,支持直接从字符串构造。
常见错误是忽略响应是否为有效 JSON:API 出错时可能返回 HTML 错误页或空响应,直接 json::parse() 会抛 nlohmann::json::parse_error 异常。
立即学习“C++免费学习笔记(深入)”;
- 先检查
curl_easy_perform()返回值是否为CURLE_OK - 再检查响应字符串长度是否 > 0,且首字符为
{或[ - 用
try-catch包住json::parse(),避免程序崩溃 - 字段访问用
["country_name"].get<std::string>(),别用.at()(越界抛异常)或[](自动插入 null)
处理 ip-api.com 的免费接口限制与错误响应
ip-api.com 免费接口(http://ip-api.com/json/{ip})看似简单,但实际使用中坑最多:它对未带 User-Agent 的请求返回 403,对高频请求返回 429,还可能返回 {"status":"fail","message":"service unavailable"} 这类非标准错误结构。
它的响应字段名也容易混淆:country 是国家名,countryCode 是两位缩写,region 是省/州代码(如 CA),而 regionName 才是“California”这种可读名。
- 永远检查
["status"].get<std::string>() == "success",不能只看 HTTP 状态码 - 若需查本地公网 IP,直接请求
http://ip-api.com/json/(不带 IP 参数),但该行为更易被限流 - 生产环境建议换用需 key 的服务(如
ipapi.co?access_key=xxx),错误响应格式统一,且有明确配额提示
绕过 DNS 和证书验证的临时调试技巧
开发初期常卡在连接失败:可能是公司内网 DNS 不通外网、或系统缺失根证书导致 HTTPS 握手失败。此时可临时关闭验证以定位问题,但上线前必须关掉。
用 libcurl 时,设置以下两个选项即可跳过:
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); // 不验证服务器证书 curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); // 不验证证书域名
但注意:CURLOPT_SSL_VERIFYPEER 关闭后,中间人攻击风险真实存在;CURLOPT_DNS_CACHE_TIMEOUT 设为 0 可禁用 DNS 缓存,避免旧解析结果干扰测试。
真正要解决的不是跳过验证,而是让 curl 找到系统证书路径(Linux 通常在 /etc/ssl/certs/ca-certificates.crt,macOS 用 brew install curl-ca-bundle,Windows 需手动指定 CURLOPT_CAINFO)。


















