libcurl是C++发送HTTP请求最成熟跨平台方案;需全局初始化、设URL/超时、检查返回值;POST JSON须设header、body及长度;响应体用WRITEFUNCTION捕获,状态码用getinfo获取;HTTPS证书失败应配CA路径而非禁用验证。

直接用 libcurl 发送 HTTP 请求是 C++ 里最成熟、跨平台也最可控的方式;没有标准库支持,别试图手写 socket 拼 HTTP 报文。
初始化和基础 GET 请求怎么写
每次请求前必须调用 curl_global_init(CURL_GLOBAL_DEFAULT),且整个进程只需一次;实际请求用 curl_easy_init() 创建句柄,设置 URL 后调用 curl_easy_perform() 即可。
常见疏漏点:
-
curl_easy_setopt()的参数顺序不能错,比如CURLOPT_URL必须传const char*,传std::string.c_str()要确保字符串生命周期覆盖请求过程 - 忘记检查
curl_easy_perform()返回值,它返回CURLE_OK才算成功,否则是网络错误(如CURLE_COULDNT_RESOLVE_HOST)或协议错误(如CURLE_HTTP_RETURNED_ERROR) - 没设超时,
curl_easy_setopt(handle, CURLOPT_TIMEOUT, 10L)建议必加,否则 DNS 卡住或服务器不响应会阻塞很久
auto handle = curl_easy_init(); if (!handle) return; curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/get"); curl_easy_setopt(handle, CURLOPT_TIMEOUT, 10L); CURLcode res = curl_easy_perform(handle); curl_easy_cleanup(handle);
POST 提交 JSON 数据的关键配置
发 JSON 不是简单把字符串塞进 CURLOPT_POSTFIELDS 就完事,HTTP 头和编码行为必须显式控制。
立即学习“C++免费学习笔记(深入)”;
必须设置的项:
-
CURLOPT_POSTFIELDS设为 JSON 字符串指针(注意不是std::string对象本身) -
CURLOPT_POSTFIELDSIZE显式传长度,避免 libcurl 错判结尾的 \0 -
CURLOPT_HTTPHEADER加"Content-Type: application/json",否则服务端可能拒收 - 如果服务端要求认证,加
"Authorization: Bearer xxx"到 header 列表里
std::string json = R"({"key":"value"})";
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(handle, CURLOPT_URL, "https://httpbin.org/post");
curl_easy_setopt(handle, CURLOPT_POSTFIELDS, json.c_str());
curl_easy_setopt(handle, CURLOPT_POSTFIELDSIZE, json.size());
curl_easy_setopt(handle, CURLOPT_HTTPHEADER, headers);
curl_easy_perform(handle);
curl_slist_free_all(headers);如何捕获响应体和状态码
默认情况下响应内容被丢弃,得用 CURLOPT_WRITEFUNCTION + CURLOPT_WRITEDATA 自定义接收逻辑;状态码需在请求后用 curl_easy_getinfo() 获取。
典型做法:
- 准备一个
std::string缓冲区,传给CURLOPT_WRITEDATA - 写一个静态回调函数,把收到的数据追加进缓冲区(注意:libcurl 可能多次调用该函数)
- 请求完成后,用
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &code)取状态码 - 不要依赖回调函数里拿到的状态码——它还没出来,得等
curl_easy_perform()返回后再查
std::string response_body;
auto write_callback = [](char* ptr, size_t size, size_t nmemb, void* userdata) -> size_t {
auto& buf = *static_cast(userdata);
buf.append(ptr, size * nmemb);
return size * nmemb;
};
curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, write_callback);
curl_easy_setopt(handle, CURLOPT_WRITEDATA, &response_body);
long http_code = 0;
curl_easy_perform(handle);
curl_easy_getinfo(handle, CURLINFO_RESPONSE_CODE, &http_code); HTTPS 证书验证失败怎么办
开发阶段遇到 CURLE_SSL_CACERT 或 CURLE_PEER_FAILED_VERIFICATION 错误,本质是 libcurl 找不到可信 CA 证书路径,或目标站点证书异常。
安全做法是配对证书路径,而非关验证:
- Linux 上通常用
/etc/ssl/certs/ca-certificates.crt,macOS 用/opt/homebrew/etc/ca-certificates/cert.pem(Homebrew 安装的 curl) - Windows 需手动下载 Mozilla CA 包,设
CURLOPT_CAINFO指向该文件 - 临时调试可设
CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST为 0L,但上线前必须撤掉 - 自签名内网服务,可用
CURLOPT_SSL_CTX_FUNCTION注入自定义验证逻辑,不过极少需要
证书路径不对比网络不通更难排查——libcurl 不会告诉你“CA 文件不存在”,只报验证失败。










