示例
1、在.pro
工程描述文件中添加网络模块
QT += network
2、示例代码
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "ui_mainwindow.h"
#include <QDebug>
#include <QWidget>
#include <QObject>
#include <QHttpMultiPart>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QMetaObject>
#include <QEventLoop>
// 以下是json数据传送所需头文件
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonValue>
#include <QJsonArray>
#include <QVariant>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow {
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow(){ delete ui; };
// 发送 http/https 的 GET 请求
void doGet(QString &url,QString &contentType) {
// 1、构建网络请求对象
QNetworkRequest req;
req.setUrl(QUrl(url));
req.setHeader(QNetworkRequest::ContentTypeHeader,QVariant(contentType));
// 2、构建网络访问管理器
QNetworkAccessManager nam;
// 3、连接 网络访问管理器的 finished 信号与当前 QWidget 组件的匿名槽函数,作用是打印响应内容
connect(&nam, &QNetworkAccessManager::finished, this, [](QNetworkReply *reply) {
QString res = reply->readAll();
qDebug() << res;
});
// 4、发起 GET 请求
QNetworkReply *resp = nam.get(req);
// 5、构建事件循环对象
QEventLoop loop;
// 6、连接 网络响应对象的 finished 信号与事件循环 的退出事件循环槽函数
connect(resp,&QNetworkReply::finished,&loop,&QEventLoop::quit);
// 7、开启事件循环
loop.exec();
}
// 发送一个 http/https 的 POST 请求
void doPost(QJsonObject &body,QString &url,QString &contentType) {
// 0、处理 POST 请求的 body
QJsonDocument document;
document.setObject(body);
// 1、将请求 json 转换为字节组
QByteArray byte_array = document.toJson(QJsonDocument::Compact);
// 2、构建网络请求对象
QNetworkRequest req;
req.setUrl(QUrl(url));
req.setHeader(QNetworkRequest::ContentTypeHeader,QVariant(contentType));
// 3、构建网络访问管理器
QNetworkAccessManager nam;
// 4、连接 网络访问管理器的 finished 信号与当前 QWidget 组件的匿名槽函数,作用是打印响应内容
connect(&nam, &QNetworkAccessManager::finished, this, [](QNetworkReply *reply) {
QString res = reply->readAll();
qDebug() << res;
});
// 5、发起 POST 请求 + 传输的数据
QNetworkReply* reply = nam.post(req, byte_array);
// 6、构建事件循环对象
QEventLoop loop;
// 7、连接 网络响应对象的 finished 信号与事件循环 的退出事件循环槽函数
connect(reply,&QNetworkReply::finished,&loop,&QEventLoop::quit);
// 8、开启事件循环
loop.exec();
}
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
注意:connect()连接函数只能在 QObject 对象之间中使用
3、测试
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QString"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
QString url = "https://blog.csdn.net/qq_39153720/article/details/122118492";
QString contentType = "application/json;charset=utf-8";
// 发起 GET 请求测试
this->doGet(url,contentType);
QJsonObject body;
// 发起 POST 请求测试
this->doPost(body,url,contentType);
}
开启SSL
Qt 使用QNetwork 模块,进行api请求时发生错误,错误信息:qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed
Qt本身是支持ssl的,但是因为法律原因?没有自带对应的dll,先使下方代码打印当前Qt版本支持的SSL
版本
解决:
#include <QSslSocket>
#include <QDebug>
qDebug()<< QSslSocket::sslLibraryBuildVersionString(); // "OpenSSL 1.1.1d 10 Sep 2019"
接下来就去下载对应版本的OpenSSL
- 方式一
下载OpenSSL源码,自行编译:https://www.openssl.org/source/
- 方式二
直接下载 dll :https://slproweb.com/products/Win32OpenSSL.html
这里推荐第二个方法,省去自己编译的时间。然后在这个网站找到对应的版本,比如刚刚打印的1.1.1,同时,也要注意工程是32位还是64位,这里选择的是Win64 OpenSSL v1.1.1n Light
至于EXE还是MSI都没差异。
安装的时候选择的是第二个,这样可以方便的进行 dll 文件的拷贝
进入OpenSSL安装目录。bin目录下,拷贝这两个dll文件到工程的exe程序所在路径下
比如这里的路径,直接放到exe 可执行文件的根路径下即可,然后程序即可正常运行。注意下方图片中黄色框出来的是旧版本的 dll ,因为有的人Qt版本可能比较低,那么打印出来的 OpenSSL 版本可能是1.0.2,那么dll名字大概率就是黄色框中的那样。
注意:这里也测试了一下,不同OpenSSL版本的dll是否可以通用,发现高低版本都不行,必须和 Qt 打印出来的OpenSSL版本一致才行。
很多帖子都说把这两个dll文件放到 E:\QT\5.12.3\mingw73_64\bin 路径下,即Qt的安装路径下。这样也可以,但是我觉得不好,个人认为尽量别去动Qt安装路径下的文件,尽量避免人为改变QT的默认开发环境,主要是为了以后排错不会导致当时自己把文件放到了Qt安装路径下太久忘记,而在别的电脑上无法正常使用的情况。
参考
QT进行http请求(post/get)
https://blog.csdn.net/qq_63986699/article/details/124998384
Qt 解决qt.network.ssl: QSslSocket::connectToHostEncrypted: TLS initialization failed问题
https://blog.csdn.net/WHEgqing/article/details/129836181
https://blog.csdn.net/BadAyase/article/details/103905615
标签:http,QT,dll,https,include,MainWindow,Qt From: https://www.cnblogs.com/hhddd-1024/p/17814756.html