问题描述:
博客网站的API全部都换成了https的网址了,以前的网络请求,就无法用了,需要用到 QNetworkManager 访问 https 开头的网址。
环境:
QT版本:5.14.2
Open SSL库版本: openssl1.1.1d
解决方案
根据网站找的资料,第一步是要确定你的QT环境支持到底是那个版本的OpenSSL库,这个很关键,不然会无法使用
测试代码:
#include "ui/mainwindow.h"
#include <QApplication>
#include <QSslSocket>
#include <QDebug>
// OpenSSL去这个网址下载指定的dll OpenSSL 1.1.1d 10 Sep 2019
//https://slproweb.com/products/Win32OpenSSL.html
void printOpenSslVersion() {
qDebug() << "OpenSSL version:" << QSslSocket::sslLibraryBuildVersionString();
}
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
printOpenSslVersion();
MainWindow w;
w.show();
return a.exec();
}
我通过测试代码看到本机支持的openssl版本:
OpenSSL version: "OpenSSL 1.1.1d 10 Sep 2019"
由于https://slproweb.com/products/Win32OpenSSL.html 这个网站上 OpenSSL 1.1.1d 版本已经没有了,所以找了个百度网盘分享的
包含Win32和Win64 的安装包
百度网盘链接:
https://pan.baidu.com/s/1SLhNDmRC-tmm86lDnEvNmw?pwd=abcd
安装之后:
安装过程和后续如何在QT中使用: 网络请求代码测试:
上层调用:
void SDKClient::SearchArticles(QString searchKeywords){
QString url_str = HOST_DOMAIN+"/xxx/xxx/list";
HttpRequestInput input(url_str, "GET");
input.add_var("title",searchKeywords);
input.add_var("page","1");
input.add_var("limit","50");
// 创建多个 Cookie
QNetworkCookie cookie1;
cookie1.setName("article.token");
cookie1.setValue(this->token.toUtf8());
cookie1.setDomain("blog.grabbyte.com");
cookie1.setPath("/");
QVector<QNetworkCookie> cookies;
cookies.append(cookie1);
HttpRequestWorker *worker = new HttpRequestWorker(this);
// 设置 cookies
worker->setCookies(cookies);
connect(worker, SIGNAL(on_execution_finished(HttpRequestWorker*)), this, SLOT(handleGetArticleListResponse(HttpRequestWorker*)));
worker->execute(&input);
}
封装的网络请求类:
HttpRequestWorker::HttpRequestWorker(QObject *parent)
: QObject(parent), manager(NULL)
{
qsrand(QDateTime::currentDateTime().toTime_t());
m_cookieJar=new QNetworkCookieJar();
manager = new QNetworkAccessManager(this);
//设置cookies
manager->setCookieJar(m_cookieJar);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(on_manager_finished(QNetworkReply*)));
if(false==QSslSocket::supportsSsl()){
qDebug()<<"不支持SSL";
}else{
QSslConfiguration SSLConfig;
SSLConfig =QSslConfiguration::defaultConfiguration();
SSLConfig.setPeerVerifyMode(QSslSocket::QueryPeer);
SSLConfig.setProtocol(QSsl::TlsV1_2);
}
#ifdef AUTH
// If htaccess authentication is required, then connect using authenticator
// Connect new slot with appropriate signal
connect(manager, SIGNAL(authenticationRequired(QNetworkReply*,QAuthenticator*)), SLOT(provideAuthentication(QNetworkReply*,QAuthenticator*)));
#endif
}
void HttpRequestWorker::on_manager_finished(QNetworkReply *reply) {
error_type = reply->error();
if (error_type == QNetworkReply::NoError) {
response = reply->readAll();
}
else {
error_str = reply->errorString();
}
reply->deleteLater();
emit on_execution_finished(this);
}
核心检测代码:
if(false==QSslSocket::supportsSsl()){
qDebug()<<"不支持SSL";
}
标准安装路径:
C:\Program Files (x86)\OpenSSL-Win32\lib\libssl.lib
C:\Program Files\OpenSSL-Win64\lib\libssl.lib
另外,还要把动态库(.dll文件)放到exe所在的目录,在用windeployqt的时候可能不会自动获取,要手动复制一下。
注意依赖的DLL名称不一样
不同版本的DLL名称有所不同,1.1.x版本的名称之前的名称有区别
例如我安装的openssl 1.1.1d 就是下面两个dll,通过资源管理器的资源监视器,看到的依赖dll是下面两个
mdblog.exe 312 libcrypto-1_1.dll C:\WINDOWS\SYSTEM32\libcrypto-1_1.dll
mdblog.exe 312 libssl-1_1.dll C:\WINDOWS\system32\libssl-1_1.dll
由于我是安装版,我直接去安装目录找到32位(如果你的exe是64位的,找64位置的dll)的dll更靠谱点,我发现通过上面的路径并没有找到对应的DLL
早期的版本,名称是下面的两个:
libeay32.dll
ssleay32.dll
自己编译
如果有兴趣自己编译的,也可以找到这个版本的源码去编译,编译过程网络上就有大把的教程了 openssl1.1.1d源码: