關於QThttp post上傳混合表單資料例項總結
阿新 • • 發佈:2018-12-01
最近使用QT做一個應用,需要使用一下幾個庫模擬http表單上傳。走了很多彎路,經過很多次實驗抓包之後,終於可以上傳成功了。
#include "QNetworkAccessManager"
#include "QUrl"
#include "QHttpMultiPart"
#include "QNetworkRequest"
qt 官網給出了一些例子,上傳文字的時候可以成功,但是等到長傳圖片的時候就有了一些問題,通過抓包分析:
1.單純上傳文字文件時候
抓包如下:正常上傳
------WebKitFormBoundaryMpB6TGuCBoHAKJej
Content -Disposition: form-data; name="tokenid"
001001
------WebKitFormBoundaryMpB6TGuCBoHAKJej
Content-Disposition: form-data; name="mid"
001
>------WebKitFormBoundaryMpB6TGuCBoHAKJej--
上傳圖片的時候:
------WebKitFormBoundaryMpB6TGuCBoHAKJej
Content-Disposition: form-data; name="tokenid"
001001
------WebKitFormBoundaryMpB6TGuCBoHAKJej
Content-Disposition: form-data; name="mid"
001
------WebKitFormBoundaryMpB6TGuCBoHAKJej--
Content-Disposition: form-data; name="pic"
asdfhsdfndfhwqdjddau7&&(此處亂碼,為二進位制或者是base64?)
------WebKitFormBoundaryMpB6TGuCBoHAKJej--
經過反覆抓取網頁向伺服器的請求取資料,發現了一個問題,就是qt官方給的歷程上少了一個Content-Disposition屬性,導致伺服器無法識別。
更改後的程式查抓包後如下:
------WebKitFormBoundaryMpB6TGuCBoHAKJej
Content-Disposition: form-data; name="tokenid"
001001
------WebKitFormBoundaryMpB6TGuCBoHAKJej
Content-Disposition: form-data; name="mid"
001
------WebKitFormBoundaryMpB6TGuCBoHAKJej--
Content-Disposition: form-data; name="pic";filename="hello.jpg"
asdfhsdfndfhwqdjddau7&&(此處亂碼,為二進位制或者是base64?)
------WebKitFormBoundaryMpB6TGuCBoHAKJej--
ok,到此資料上傳成功。一下為部分程式碼,可實現上傳圖片和文字資訊到伺服器:
程式碼:
void Controler::upDatasToCloud()
{
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
/* tokenid */
QHttpPart textPart; textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"tokenid\""));
textPart.setBody("001001");
multiPart->append(textPart);
/* mid */
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"mid\""));
textPart.setBody(this->ui.lineEdit_no->text().toUtf8());
multiPart->append(textPart);
QHttpPart imagePart;
imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));
imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"pic1\"; filename=\""+path_face+"\""));
QFile *file = new QFile(path_face);
file->open(QIODevice::ReadOnly);
imagePart.setBodyDevice(file);
//file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart
multiPart->append(imagePart);
QHttpPart imagePart1;
imagePart1.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
imagePart1.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"pic2\"; filename=\""+path_shetai+"\""));
QFile *file1 = new QFile(path_shetai);
file1->open(QIODevice::ReadOnly);
imagePart1.setBodyDevice(file1);
//file1->setParent(multiPart);
multiPart->append(imagePart1);
QUrl url("http:your post url");
QNetworkRequest *request=new QNetworkRequest(url);
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) {
this->ui.label_add->setText(QString::number(((float)a) / b));
});
QObject::connect(reply, &QNetworkReply::readyRead, [=]() {
qDebug() << "rpy:"<< reply->errorString() << reply->readAll();
//檔案關閉很多種,但是切記不能提前關閉,否則上傳進度卡死。
file->close();
file1->close();
});
}
這個函式就可以實現混合資料表單上傳了,切記加入filename屬性,否則真的很無奈。