QT中的网络请求
一、主程序(main.cpp)
#include <QCoreApplication>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QUrlQuery>
#include <QJsonDocument>
#include <QJsonObject>
#include <QDebug>// 全局网络管理器(需在事件循环中使用)
QNetworkAccessManager* manager = nullptr;// 处理 POST 请求的响应
void handleReply(QNetworkReply* reply) {// 检查是否有错误if (reply->error() != QNetworkReply::NoError) {qDebug() << "请求失败,错误信息:" << reply->errorString();reply->deleteLater(); // 释放资源return;}// 读取响应数据(二进制格式)QByteArray responseData = reply->readAll();qDebug() << "响应内容:" << responseData;// 可选:解析 JSON 响应(假设服务端返回 JSON)QJsonParseError parseError;QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData, &parseError);if (parseError.error == QJsonParseError::NoError) {QJsonObject jsonObj = jsonDoc.object();qDebug() << "解析后的 JSON 数据:" << jsonObj.toVariantMap();}// 释放资源(异步释放,避免直接 delete)reply->deleteLater();// 退出事件循环(控制台程序示例结束)QCoreApplication::quit();
}// 发送 POST 请求(表单数据)
void postFormData() {QNetworkRequest request;// 设置目标 URL(示例用 httpbin.org 的测试接口)request.setUrl(QUrl("https://httpbin.org/post"));// 设置 Content-Type(表单数据格式)request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");// 构造表单数据(键值对)QUrlQuery postData;postData.addQueryItem("username", "doubao");postData.addQueryItem("password", "123456");postData.addQueryItem("role", "tester");// 发送 POST 请求QNetworkReply* reply = manager->post(request, postData.toString(QUrl::FullyEncoded).toUtf8());// 关联响应处理槽函数QObject::connect(reply, &QNetworkReply::finished, [=]() { handleReply(reply); });
}// 发送 POST 请求(JSON 数据)
void postJsonData() {QNetworkRequest request;request.setUrl(QUrl("https://httpbin.org/post"));// 设置 Content-Type(JSON 格式)request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");// 构造 JSON 数据QJsonObject jsonData;jsonData["username"] = "doubao";jsonData["password"] = "123456";jsonData["is_vip"] = true;QJsonDocument jsonDoc(jsonData);QByteArray jsonBody = jsonDoc.toJson();// 发送 POST 请求QNetworkReply* reply = manager->post(request, jsonBody);QObject::connect(reply, &QNetworkReply::finished, [=]() { handleReply(reply); });
}int main(int argc, char *argv[]) {QCoreApplication a(argc, argv);// 初始化网络管理器manager = new QNetworkAccessManager(&a);// 选择发送方式(示例发送表单数据,可改为 postJsonData() 测试 JSON)postFormData();// 启动事件循环(必须,否则无法接收网络响应)return a.exec();
}
二、核心组件
- QNetworkAccessManager:Qt 网络模块的核心类,负责管理网络请求(发送 GET/POST 等)。
- QNetworkRequest:封装请求信息(URL、请求头、超时设置等)。
- QNetworkReply:表示一个网络请求的响应,用于读取数据或处理错误。
三、关键步骤
-
设置请求头:
- 表单数据需设置
Content-Type: application/x-www-form-urlencoded
。 - JSON 数据需设置
Content-Type: application/json
。
- 表单数据需设置
-
构造请求体:
- 表单数据用
QUrlQuery
生成键值对(自动编码)。 - JSON 数据用
QJsonObject
+QJsonDocument
生成标准 JSON 字符串。
- 表单数据用
-
异步处理响应:
- 通过
QNetworkReply::finished
信号监听请求完成事件。 - 使用
reply->error()
检查错误,reply->readAll()
读取响应内容。
- 通过
四、测试验证
- 编译运行程序,控制台会输出以下内容(以表单数据为例):
响应内容: "{\"args\":{},\"data\":\"\",\"files\":{},\"form\":{\"password\":\"123456\",\"role\":\"tester\",\"username\":\"doubao\"},...}" 解析后的 JSON 数据: QMap(("args", QVariant(QMap,())), ("data", QVariant(QString, "")), ...)
- 若需测试 JSON 数据,将
main
函数中的postFormData()
改为postJsonData()
即可。
五、注意事项
- HTTPS 支持:若目标 URL 为 HTTPS(如示例中的
https://httpbin.org/post
),需确保 Qt 编译时启用了 OpenSSL 支持(Windows 需将libeay32.dll
和ssleay32.dll
放入程序目录)。 - 编码问题:表单数据用
QUrlQuery::toString(QUrl::FullyEncoded)
自动编码,避免中文乱码。 - 资源释放:使用
reply->deleteLater()
异步释放响应对象,避免内存泄漏。