Qt - Qt中HTTP相关的类
前言
本篇文章来给大家讲解QT中的Http协议,Http协议主要用于网络中数据的请求和响应,那么这篇文章将给大家讲解一下这个协议。
1、HTTP协议概述
HTTP(超文本传输协议)是互联网上应用最为广泛的协议之一,它定义了客户端和服务器之间进行通信的规则。HTTP是一种无状态的协议,它通过请求-响应模型来实现客户端和服务器之间的数据传输。
以下是HTTP的一般工作流程:
1.客户端发送HTTP请求:客户端(通常是Web浏览器)向服务器发送HTTP请求。请求由以下部分组成:
请求方法(GET、POST、PUT、DELETE等):指定服务器执行的操作类型。
资源路径:指定要访问的服务器上的资源路径。
请求头:包含有关请求的其他元数据,如请求的主机、内容类型等。
请求正文(对于某些请求方法):包含请求所携带的数据。
2.服务器处理请求:服务器接收并解析HTTP请求,执行相应的操作:
检查请求的合法性和安全性。
处理请求中指定的资源或执行请求中指定的操作。
构造HTTP响应。
3.服务器发送HTTP响应:服务器生成HTTP响应,响应由以下部分组成:
状态码:指示请求是否成功或出现错误的数字代码。
响应头:包含有关响应的元数据,如响应的内容类型、长度等。
响应正文:包含服务器返回给客户端的实际数据。
4.客户端接收HTTP响应:客户端接收并解析HTTP响应:
检查响应的状态码以确定请求的成功与否。
解析响应头以获取响应的元数据。
处理响应正文中的数据。
HTTP使用TCP协议作为传输协议,默认使用80端口进行通信。它是一种无连接协议,这意味着每个请求都是独立的,服务器不会保留先前请求的状态信息。为了在请求之间保持状态,可以使用Cookie或会话等机制。
此外,HTTP还支持各种请求方法,最常见的是GET和POST。GET方法用于从服务器获取资源,而POST方法用于向服务器提交数据。
总结起来,HTTP是一种用于在客户端和服务器之间传输数据的协议。它为Web应用程序提供了通信和数据交换的基础,是实现互联网应用的核心之一
2、HTTP的两种模型
1.B/S模型
B/S模型是一种基于浏览器和服务器的交互模型,通常用于Web应用程序。在这种模型中,客户端使用浏览器作为前端界面,通过HTTP协议与服务器进行通信。客户端(浏览器)负责显示用户界面,发送HTTP请求,并接收和渲染服务器返回的HTML、CSS和JavaScript等资源。服务器负责存储数据、处理业务逻辑和生成动态网页内容。B/S模型具有以下特点:
客户端只需安装浏览器,无需安装额外客户端软件。
应用程序部署在服务器上,用户通过浏览器访问。
跨平台性好,可以在不同操作系统和设备上使用。
2.C/S模型
C/S模型是一种基于客户端和服务器的交互模型,常用于传统的桌面应用程序。在这种模型中,客户端通过安装在本地计算机上的客户端软件与服务器进行通信。客户端负责处理用户界面和部分业务逻辑,发送请求到服务器并接收响应。服务器负责处理业务逻辑和存储数据。C/S模型具有以下特点:
需要在客户端安装相应的客户端软件,适用于特定平台和操作系统。
应用程序的逻辑部分可以在客户端执行,减轻服务器的负担。
可以通过局域网或互联网与服务器进行通信。
可以实现一些功能更复杂、操作更强大的应用程序。
3、HTTP请求报文
请求报文是由客户端发送给服务器,用于请求特定资源或执行特定操作。它由以下几个部分组成:
请求行:描述了请求的方法、目标资源的路径和HTTP协议的版本,通常包含以下三个字段:
请求方法:指定了客户端希望服务器执行的操作,如GET、POST、PUT、DELETE等。
请求目标:表示客户端希望访问的资源路径,可以是绝对路径或相对路径。
协议版本:指定所使用的HTTP协议的版本,如HTTP/1.1。
请求头:包含了关于请求的附加信息,格式为键值对。常见的请求头字段包括:
Host:指定请求的目标主机。
User-Agent:标识发送请求的客户端应用程序。
Content-Type:指定请求正文的类型。
请求正文(可选):包含客户端发送给服务器的数据,通常在使用POST等方法时使用。
4、HTTP响应报文
响应报文是服务器对客户端请求的回应,包含了所请求资源的数据或执行结果。它由以下几个部分组成:
状态行:描述了响应的状态,包含以下三个字段:
协议版本:指定所使用的HTTP协议的版本,如HTTP/1.1。
状态码:表示服务器对请求的处理结果,如200表示成功,404表示资源未找到。
状态信息:对状态码进行简短的解释说明。
响应头:包含了关于响应的附加信息,格式为键值对。常见的响应头字段包括:
Content-Type:指定响应正文的类型。
Content-Length:指定响应正文的长度。
Set-Cookie:在响应中设置Cookie。
响应正文:包含了服务器返回给客户端的数据,可以是HTML、JSON、文件等。
5、调试软件Postman
Postman是一款广泛使用的API开发和测试工具,它提供了一个强大的图形用户界面(GUI),用于发送HTTP请求、测试和调试API。
安装非常简单最近在百度查找进行下一步安装即可:
在postman软件中可以请求到JSON格式的数据:
6、QT中的HTTP类
Qt中处理HTTP请求和响应相关的类
类名 | 主要功能 |
QNetworkAccessManager | 用于发送HTTP请求和接收响应的类。 |
QNetworkRequest | 表示HTTP请求的类,可以设置请求URL、请求头等信息。 |
QNetworkReply | 表示HTTP响应的类,可以读取响应的内容、错误处理等。 |
QNetworkCookieJar | 用于管理HTTP请求和响应中的Cookie类。 |
QNetworkCookie | 表示HTTP请求和响应中的Cookie的类。 |
QNetworkProxy | 表示网络代理的类,可以设置代理服务器来处理HTTP请求和响应。 |
在Qt中,用于进行HTTP通信的类是QNetworkAccessManager类和相关的类。QNetworkAccessManager提供了一个用于发送网络请求和接收网络响应的高层API,它基于Qt的网络模块实现。
以下是一些与HTTP通信相关的类和其主要功能:
QNetworkAccessManager类:
该类用于发送HTTP请求和接收HTTP响应。
可以发起GET、POST、PUT、DELETE等各种类型的请求。
提供了信号和槽机制,允许处理请求的完成、错误和响应等事件。
支持同步和异步方式发送请求。
QNetworkRequest类:
表示一个HTTP请求。
可以设置请求的URL、请求头、请求方法等属性。
可以添加自定义的请求头字段。
QNetworkReply类:
表示一个HTTP响应。
提供了获取响应状态码、响应头、响应正文等信息的方法。
可以通过该类获取服务器返回的数据。
QNetworkCookieJar类:
用于管理和存储HTTP请求和响应中的Cookie。
可以设置和获取Cookie,并将其与请求关联起来。
这些类的组合使用可以实现在Qt应用程序中进行HTTP通信的功能。以下是一个简单的示例代码,演示如何使用QNetworkAccessManager发送GET请求并处理响应:
7、使用HTTP类请求数据
使用HTTP类请求数据步骤:
1.使用QNetworkAccessManager类创建网络访问管理器
2.使用QNetworkRequest创建请求对象
3.使用QNetworkReply发出GET请求(在请求完成后一定要记得使用deleteLater来清理释放资源)
4.连接信号与槽得到数据
示例1:
此方式使用了 Lambda 表达式连接信号与槽
#include <QCoreApplication>
#include <QDebug>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// 创建网络访问管理器
QNetworkAccessManager m_manger;
// 创建请求对象
QNetworkRequest request;
QUrl url("http://www.baidu.com");
request.setUrl(url);
// 发出GET请求
QNetworkReply* reply = m_manger.get(request);
// 连接请求完成的信号
QObject::connect(reply, &QNetworkReply::finished, [&]() {
// 读取响应数据
QByteArray responseData = reply->readAll();
qDebug() << responseData;
// 请求完成后,清理资源
reply->deleteLater();
qApp->quit();
});
return a.exec();
}
代码改进版本:
此方式就是槽函数单独分开写了,原理与上面一样的。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
public slots:
void handleNetworkResponse();
private:
Ui::Widget *ui;
// 创建网络访问管理器
QNetworkAccessManager m_manger;
QNetworkReply* m_reply;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{
ui->setupUi(this);
// 创建请求对象
QNetworkRequest request;
QUrl url("https://www.leawo.org/images/7days_prom_en.jpg");
request.setUrl(url);
// 发出GET请求
m_reply = m_manger.get(request);
// 连接请求完成的信号
QObject::connect(m_reply, &QNetworkReply::finished, this, &Widget::handleNetworkResponse);
}
Widget::~Widget()
{
delete ui;
}
void Widget::handleNetworkResponse()
{
// 读取响应数据
QByteArray responseData = m_reply->readAll();
qDebug() <<"responseData = " <<responseData;
// 请求完成后,清理资源
m_reply->deleteLater();
}
运行结果:
示例2:
widget.h
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
// QT += network
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QHttpPart>
#include <QHttpMultiPart>
#include <QFile>
#include <QTimer>
namespace Ui {
class MainWidget;
}
class MainWidget : public QWidget
{
Q_OBJECT
public:
explicit MainWidget(QWidget *parent = nullptr);
~MainWidget();
//get请求测试
void getTest();
//post请求测试
void postTest();
//表单测试
void formTest();
public slots:
//获取异步结果
void receiveReply(QNetworkReply *reply);
private:
Ui::MainWidget *ui;
QNetworkAccessManager *manager;
QTimer timer;
};
#endif // MAINWIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QUrlQuery>
#include <QJsonArray>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonValue>
#include <QDebug>
MainWidget::MainWidget(QWidget *parent) :
QWidget(parent),
ui(new Ui::MainWidget)
{
ui->setupUi(this);
manager=new QNetworkAccessManager(this);
//查看支持的协议
qDebug()<<manager->supportedSchemes();
//安装了openssl,会有https
//("ftp", "file", "qrc", "http", "data")
//QNetworkAccessManager是异步的
connect(manager, &QNetworkAccessManager::finished, this, &MainWidget::receiveReply);
//测试get
connect(ui->btnGet,&QPushButton::clicked,this,&MainWidget::getTest);
//测试post
connect(ui->btnPost,&QPushButton::clicked,this,&MainWidget::postTest);
//测试form
connect(ui->btnForm,&QPushButton::clicked,this,&MainWidget::formTest);
//定时器拿来验证是否阻塞界面
connect(&timer,&QTimer::timeout,this,[this]()
{
ui->editTime->setTime(QTime::currentTime());
});
timer.start(1000); //定时1s
}
MainWidget::~MainWidget()
{
delete ui;
}
void MainWidget::getTest()
{
//构建请求对象
QNetworkRequest request;
request.setUrl(QUrl(ui->editGetUrl->text()));
//设置请求头
//已知头类型参见文档QNetworkRequest::KnownHeaders
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
//自定义类型
request.setRawHeader("self-header","gongjianbo");
//发送请求
manager->get(request);
//同步处理,可以开启一个局部的事件循环,等待响应,不会阻塞线程
//QNetworkReply *reply=manager->get(request);
//QEventLoop eventLoop;
//connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
//eventLoop.exec();
//receiveReply(reply);
//超时处理,可以使用定时器调用abort、close来终止当前的请求
//QNetworkReply *reply=manager->get(request);
//if(reply->isRunning()){
// QTimer *timer=new QTimer(reply);//对象树关联释放,也可以在finish进行释放
// timer->setSingleShot(true);
// //超时就结束
// connect(timer,&QTimer::timeout,reply,&QNetworkReply::abort);
// //结束就关定时器
// connect(reply,&QNetworkReply::finished,timer,&QTimer::stop);
// //定时
// timer->start(5000);
//}
}
void MainWidget::postTest()
{
//构建请求对象
QNetworkRequest request;
request.setUrl(QUrl(ui->editPostUrl->text()));
//设置请求头
request.setHeader(QNetworkRequest::ContentTypeHeader,"application/json");
//发送请求
manager->post(request,ui->editPostData->toPlainText().toUtf8());
}
void MainWidget::formTest()
{
QNetworkAccessManager manager2;
//构建一个multiPart用于提交表单
//注意,multiPart请在请求完成后再删除
QHttpMultiPart *multiPart=new QHttpMultiPart(QHttpMultiPart::FormDataType);
//文本内容
QHttpPart namePart;
//Content-Type对照表详情百度http://tool.oschina.net/commons/
namePart.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/plain"));
namePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"thename\";"));
namePart.setBody("gongjianbo");
QHttpPart agePart;
agePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"theage\";"));
agePart.setBody("27");
multiPart->append(namePart);
multiPart->append(agePart);
//文件内容
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("text/plain")); //我用application传各种类型文件
//示例里没有filename,导致提交不成功
filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"thefile\";filename=\"file.txt\";"));
QFile *textFile = new QFile(":/file.txt");
textFile->setParent(multiPart); //在删除reply时一并释放
if(textFile->open(QIODevice::ReadOnly)){
//要读取小块数据,请使用setBody(); 对于像图像这样的较大数据块,请使用setBodyDevice()。
filePart.setBodyDevice(textFile);
multiPart->append(filePart);
}
//图片内容
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
//示例里没有filename,导致提交不成功
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"theimage\";filename=\"image.png\";"));
QFile *imageFile = new QFile(":/image.png");
imageFile->setParent(multiPart); //在删除reply时一并释放
if(imageFile->open(QIODevice::ReadOnly)){
imagePart.setBodyDevice(imageFile);
multiPart->append(imagePart);
}
//在我们公司里使用的时候,没有Boundary也会导致提交不成功
multiPart->setBoundary("qtdata");
QNetworkRequest request(QUrl("http://httpbin.org/post"));
request.setRawHeader("Content-Type","multipart/form-data;boundary=qtdata");
//提交表单
QNetworkReply *reply=manager2.post(request,multiPart);
multiPart->setParent(reply); //在删除reply时一并释放
QEventLoop eventLoop;
connect(reply, &QNetworkReply::finished, &eventLoop, &QEventLoop::quit);
eventLoop.exec();
qDebug()<<"reply:"<<reply->readAll();
reply->deleteLater();
}
void MainWidget::receiveReply(QNetworkReply *reply)
{
//请求方式get、post等,对应QNetworkAccessManager的Operation枚举
//对于restful接口需要判断此枚举
qDebug()<<"operation:"<<reply->operation();
//路径
qDebug()<<"url:"<<reply->url();
//状态码
const int status_code = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
qDebug()<<"status code:"<<status_code;
//主动调用QNetworkReply的close或者abort也会触发finished,这时状态码为0
//访问失败状态码也会为0
if(status_code == 0 && reply->errorString() == "Operation canceled")
{
qDebug()<<"timeout";
}
if(reply->error() != QNetworkReply::NoError)
{
//处理中的错误信息
qDebug()<<"reply error:"<<reply->errorString();
}
else
{
//重定向
if (status_code == 301 || status_code == 302){
// Or the target URL if it was a redirect:
QVariant redirectionTargetUrl =reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
qDebug() << "redirection Url is " << redirectionTargetUrl.toString();
QUrl url(redirectionTargetUrl.toString());
manager->get(QNetworkRequest(url));
}
//获取响应信息并展示到ui,这里没有解析
const QByteArray reply_data = reply->readAll();
//qDebug()<<"read all:"<<reply_data;
ui->editRecv->append("[Reply] "+QTime::currentTime().toString("hh:mm:ss"));
//根据自己的编码选用对应的QString方法
ui->editRecv->append(QString::fromUtf8(reply_data));
//解析json
/*QJsonParseError json_error;
QJsonDocument document=QJsonDocument::fromJson(reply_data, &json_error);
if (json_error.error==QJsonParseError::NoError) {
if(document.isObject()){
const QJsonObject obj=document.object();
qDebug()<<obj;
if(obj.contains("args")){
QJsonValue value=obj.value("args");
qDebug()<<value;
//QJsonValue(object, QJsonObject({"ie":"utf-8"}))
}
}
}else{
qDebug()<<"json error:"<<json_error.errorString();
}*/
}
reply->deleteLater();
}
widget.ui
运行结果:
注:Qt默认是无法对https网站进行请求的,用请求http的方式下载https网站没有数据,在pro文件中添加 Qt += network,在初始程序中加入
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
qDebug() << manager->supportedSchemes();
运行后会在输出界面显示
没有https说明你的qt不能请求https网站,对此我们需要下载openSSL来实现qt对https的请求
openSSL的网站为:http://slproweb.com/products/Win32OpenSSL.html
下载对应的exe,注意要对应你的Qt的64/32位,下Light版本的就可以。
下载完之后的后续操作可以阅读这篇文章:https://www.cnblogs.com/zhuchunlin/p/18431631
8、使用Http协议进行通信
在使用Qt框架进行应用开发的过程中,很多时候需要进行客户端与服务端的网络通信,这时候就需要Qt的internet模块。而网络通信中最常用的协议就是http协议,Qt对http协议的调用进行了封装,使用非常方便。这里对常用的http请求demo做一下总结,方便大家参考。
在使用internet模块时需要在pro文件中添加对应的模块。
QT += network
Qt中使用Http协议与服务端通信的请求主要分为GET和POST,GET是从指定的资源请求数据,而POST是向指定的资源提交要被处理的数据。
常用的请求类型包括五类:
1.多个独立参数GET请求
2.参数数组GET请求
3.上传参数数据POST请求
4.上传参数和文件POST请求
5.下载文件GET请求
下面通过简单的Demo描述五种请求的调用方式。
1.多个独立参数GET请求
int NormalGetRequest(QString paramer1, QString paramer2)
{
//生成对应的网络请求
QNetworkRequest request;
QString scheme = "http";
QString serverAddr = "192.168.0.1";
QString port = "80";
QString requestHeader = scheme + QString("://") + serverAddr + QString(":") + port;
QString fullRequest = requestHeader + QString("/api/vi/user/getrequest?paramer1=%1¶mer2=%2").arg(paramer1).arg(paramer2);
request.setUrl(QUrl(fullRequest));
//发送Get请求
QNetworkAccessManager manager;
QNetworkReply *reply = manager.get(request);
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()),&eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
//对请求的返回异常进行处理
if(reply->error() != QNetworkReply::NoError)
{
return reply->error();
}
//解析返回的Json结果
QByteArray replyData = reply->readAll();
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
if(json_error.error != QJsonParseError::NoError)
{
return -1;
}
QJsonObject rootObj = jsonDoc.object();
QString codeStr = rootObj.value("code").toString();
if (codeStr.compare("200") == 0)
{
//返回代码为200的时候证明请求成功对包含的结构数据进行处理
if(rootObj.contains("result"))
{
}
return 0;
}
else
{
//请求失败对对应的处理
return codeStr.toInt();
}
}
2.参数数组GET请求
int GetRequestWithArray(QVector<QString> m_filePathVector)
{
QJsonArray array;
for(int index=0; index<m_filePathVector.size(); ++index)
{
QJsonObject object;
object.insert("index",QString::number(index));
object.insert("path",m_filePathVector.at(index));
array.append(object);
}
QJsonDocument document;
document.setArray(array);
QString arrayString = document.toJson(QJsonDocument::Compact);
//生成对应的网络请求
QNetworkRequest request;
QString scheme = "http";
QString serverAddr = "192.168.0.1";
QString port = "80";
QString requestHeader = scheme + QString("://") + serverAddr + QString(":") + port;
QString fullRequest = requestHeader + QString("/api/vi/user/getarray?paramers=%1").arg(arrayString);
request.setUrl(QUrl(fullRequest));
//获取错误
QNetworkAccessManager manager;
QNetworkReply *reply = manager.get(request);
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()),&eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
if(reply->error() != QNetworkReply::NoError)
{
return reply->error();
}
//解析返回的Json结果
QByteArray replyData = reply->readAll();
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
if(json_error.error != QJsonParseError::NoError)
{
return -1;
}
QJsonObject rootObj = jsonDoc.object();
QString codeStr = rootObj.value("code").toString();
if (codeStr.compare("200") == 0)
{
//返回代码为200的时候证明请求成功对包含的结构数据进行处理
if(rootObj.contains("result"))
{
}
return 0;
}
else
{
//请求失败对对应的处理
return codeStr.toInt();
}
}
3.上传参数数据POST请求
int NormalPostRequest(QString paramer1, QString paramer2)
{
//生成对应的网址请求
QNetworkRequest request;
QString scheme = "http";
QString serverAddr = "192.168.0.1";
QString port = "80";
QString requestHeader = scheme + QString("://") + serverAddr + QString(":") + port;
QString fullRequest = requestHeader + "/api/v1/user/postrequest";
request.setUrl(QUrl(fullRequest));
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
//获取对应的参数数据
QByteArray data;
data.append("paramer1=");
data.append(paramer1.toUtf8());
data.append("¶mer2=");
data.append(paramer2.toUtf8());
//发送请求
QNetworkAccessManager manager;
QNetworkReply *reply = manager.post(request,data);
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()),&eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
if(reply->error() != QNetworkReply::NoError)
{
return reply->error();
}
//解析返回的Json结果
QByteArray replyData = reply->readAll();
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
if(json_error.error != QJsonParseError::NoError)
{
return -1;
}
QJsonObject rootObj = jsonDoc.object();
QString codeStr = rootObj.value("code").toString();
if (codeStr.compare("200") == 0)
{
//返回代码为200的时候证明请求成功对包含的结构数据进行处理
if(rootObj.contains("result"))
{
}
return 0;
}
else
{
//请求失败对对应的处理
return codeStr.toInt();
}
}
4.上传参数和文件POST请求
int PostRequestWithFile(QString paramer1, QString paramer2,QString filePath)
{
//生成对应的网址请求
QFileInfo fileInfo(filePath);
QString fileName =fileInfo.fileName();
QFile* inputFile = new QFile(filePath);
inputFile->open(QIODevice::ReadOnly);
//multipart请求
QHttpMultiPart* multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
//文件块
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QVariant(QString("form-data; name=\"uploadfile\";filename=\"%1\"").arg(fileName)));
filePart.setBodyDevice(inputFile);
inputFile->setParent(multiPart);
multiPart->append(filePart);
QHttpPart paramer1Part;
paramer1Part.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"paramer1\""));
paramer1Part.setBody(paramer1.toUtf8());
multiPart->append(paramer1Part);
QHttpPart paramer2Part;
paramer2Part.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"paramer2\""));
paramer2Part.setBody(paramer2.toUtf8());
multiPart->append(paramer2Part);
//生成对应的网址请求
QNetworkRequest request;
QString scheme = "http";
QString serverAddr = "192.168.0.1";
QString port = "80";
QString requestHeader = scheme + QString("://") + serverAddr + QString(":") + port;
QString fullRequest = requestHeader + "/api/v1/user/postrequestwithfile";
request.setUrl(QUrl(fullRequest));
//发送请求
QNetworkAccessManager manager;
QNetworkReply *reply = manager.post(request,multiPart);
multiPart->setParent(reply);
QEventLoop eventLoop;
QObject::connect(&manager, SIGNAL(finished(QNetworkReply*)),&eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
if(reply->error() != QNetworkReply::NoError)
{
return reply->error();
}
//解析返回的Json结果
QByteArray replyData = reply->readAll();
QJsonParseError json_error;
QJsonDocument jsonDoc(QJsonDocument::fromJson(replyData, &json_error));
if(json_error.error != QJsonParseError::NoError)
{
return -1;
}
QJsonObject rootObj = jsonDoc.object();
QString codeStr = rootObj.value("code").toString();
if (codeStr.compare("200") == 0)
{
//返回代码为200的时候证明请求成功对包含的结构数据进行处理
if(rootObj.contains("result"))
{
}
return 0;
}
else
{
//请求失败对对应的处理
return codeStr.toInt();
}
}
5. 下载文件GET请求
int DownloadFileFromWeb(QString fileUrl,QString&fileSavePath)
{
QNetworkRequest request;
QUrl url(fileUrl);
QFileInfo fileInfo(url.path());
QString fileName = fileInfo.fileName();
QNetworkAccessManager *accessManager=new QNetworkAccessManager();
request.setUrl(url);
QNetworkReply *reply = accessManager->get(request);
QEventLoop loop;
QObject::connect(accessManager, SIGNAL(finished(QNetworkReply*)), &loop, SLOT(quit()));
//如果需要下载进度需要关联对应的信号
//connect(reply, SIGNAL(downloadProgress(qint64, qint64)), this, SLOT(LoadProgress(qint64, qint64)));
loop.exec(QEventLoop::ExcludeUserInputEvents);
//获取下载返回值
QVariant statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute);
if (statusCode.toInt() != 200)
{
return -1;
}
//保存下载的文件
QFile file(fileSavePath);
if(!file.open(QIODevice::WriteOnly))
{
return -2;
}
file.write(reply->readAll());
file.close();
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?