关于QThttp post上传混合表单数据实例总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/dyingstraw/article/details/79167307

最近使用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属性,否则真的很无奈。

猜你喜欢

转载自blog.csdn.net/dyingstraw/article/details/79167307