QT http POST上传混合表单数据实例总结
要点强调
1、抓包工具抓出来的内容和填充头信息、Content-Type、Content-Disposition的顺序都是对应的。
2、boundary="boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM="这个boundary中时请求时自动生成的随机码,不用人为刻意去生成。
3、抓包工具很重要,本文使用Fiddler抓包工具。
1 抓包 Request Headers 信息
2 抓包 Raw Headers 信息
POST /serverFile HTTP/1.1
binfile-md5: binfile-md5
binfile-gzip: binfile-gzip
binfile-auth: binfile-auth
Content-Type: multipart/form-data; boundary="boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM="
MIME-Version: 1.0
Content-Length: 470
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en,*
User-Agent: Mozilla/5.0
3 抓包 TextView 信息
--boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM=
Content-Disposition: form-data; name="binFile"; filename="PSPE_PTQ_REQ_65010101_20191024162025446.json"
Content-Type: application/json
{"authStr":"65010101_AdtWPh2u","reqSender":"65010101","version":"201906131730","serviceSystem":"ISS"}
--boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM=
Content-Disposition: form-data; name="filename"
PSPE_PTQ_REQ_65010101_20191024162025446.json
--boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM=--
4 抓包 Raw 信息
POST http://192.168.0.131:8888/serverFile HTTP/1.1
binfile-md5: binfile-md5
binfile-gzip: binfile-gzip
binfile-auth: binfile-auth
Content-Type: multipart/form-data; boundary="boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM="
MIME-Version: 1.0
Content-Length: 470
Connection: Keep-Alive
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,en,*
User-Agent: Mozilla/5.0
Host: 192.168.0.131:8888
--boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM=
Content-Disposition: form-data; name="binFile"; filename="PSPE_PTQ_REQ_65010101_20191024162025446.json"
Content-Type: application/json
{"authStr":"65010101_AdtWPh2u","reqSender":"65010101","version":"201906131730","serviceSystem":"ISS"}
--boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM=
Content-Disposition: form-data; name="filename"
PSPE_PTQ_REQ_65010101_20191024162025446.json
--boundary_.oOo._MTgyNzc=MjA3ODQ=MTU1NzM=--
5 Qt 代码实现部分
5.1*.h部分
#include <QHttpMultiPart>
#include <QHttpPart>
#include <QFile>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QDebug>
5.2 *.cpp部分
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"binFile\"; filename=\"PSPE_PTQ_REQ_65010101_20191024162025446.json\""));
textPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
QFile *Jsonfile = new QFile("D://PSPE_PTQ_REQ_65010101_20191024162025446.json");
Jsonfile->open(QIODevice::ReadOnly);
textPart.setBodyDevice(Jsonfile);
//Jsonfile->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart,此句话使用时候要删掉否则会失败
multiPart->append(textPart);
QHttpPart fileNamePart;
fileNamePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"filename\""));
fileNamePart.setBody("PSPE_PTQ_REQ_65010101_20191024162025446.json");
multiPart->append(fileNamePart);
QUrl url("http://192.168.0.131:8888/serverFile");
QNetworkRequest *request=new QNetworkRequest(url);
//设置自定义的头部信息
request->setRawHeader("binfile-md5","binfile-md5");
request->setRawHeader("binfile-gzip","binfile-gzip");
request->setRawHeader("binfile-auth","binfile-auth");
QNetworkAccessManager *manager =new QNetworkAccessManager();
QNetworkReply *reply = manager->post(*request, multiPart);
multiPart->setParent(reply); // delete the multiPart with the reply
// here connect signals etc.
//更新上传进度
QObject::connect(reply, &QNetworkReply::uploadProgress, [this](int a, int b) {
ui->label->setText(QString::number(((float)a) / b));
});
QObject::connect(reply, &QNetworkReply::readyRead, [=]() {
qDebug() << "rpy:"<< reply->errorString() << reply->readAll();
//文件关闭很多种,但是切记不能提前关闭,否则上传进度卡死。
Jsonfile->close();
});