qt post上传文件

QNetworkAccessManager的post接口可以接收多种参数,一般使用QByteArray发送普通文本请求,如果要带文件内容做参数,就需要用到QHttpMultiPart类型的参数,封装formData

这里定义的是一个static成员函数

static void postWithFile(const QString url, QMap<QString, QString> &params, QMap<QString, QString> &files);

实现

void SC_HttpClient::postWithFile(const QString url, QMap<QString, QString> &params, QMap<QString, QString> &files)
{
    QMap<QString, QString>::iterator it;
    QHttpMultiPart mMultiPart(QHttpMultiPart::FormDataType);


    //QVector<QHttpPart> qFilePart;
    QVector<QFile*> qFiles;
    for(it = files.begin(); it != files.end(); ++it){
        QHttpPart filePart;
        
        //有多个文件时不能直接使用QFile file(path),for代码块结束的时候就会被析构,导致数据无法发送,程序crash
        //单个文件可以不用for遍历,直接QFile file(path)本接口结束时才会析构        
        QFile *file = new QFile(it.value());
        file->open(QFile::ReadOnly);
        qFiles.push_back(file);
        
        filePart.setBodyDevice(file);//这里的file对象就是我们需要提交的文件,如果需要上传多个文件,我们就需要创建多个QHttpPart对象
        filePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg"));//这里我们上传的是图片
        filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"" + it.key() + "\"; filename=\""+file->fileName()+"\""));//这里的name默认情况下file,如果服务器那边有特别指定就需要改成服务器指定的名字
        mMultiPart.append(filePart);
    }

    for(it = params.begin(); it != params.end(); ++it){
        QHttpPart dataPart;
        dataPart.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("text/plain"));
        dataPart.setHeader(QNetworkRequest::ContentDispositionHeader,QVariant("form-data; name=\"" + it.key() + "\""));
        dataPart.setBody(it.value().toUtf8());
        mMultiPart.append(dataPart);
    }

    QNetworkRequest request(url);
    QNetworkAccessManager nam;
    QNetworkReply* reply = nam.post(request,&mMultiPart);

    //这里定义了QEventLoop 并且连接信号槽 用于阻塞,当然也可以直接通过信号槽实现异步接收消息
    QEventLoop loop;
    connect(reply,&QNetworkReply::finished,&loop,&QEventLoop::quit);
    loop.exec();

    QVector<QFile*> ::iterator iv;
    for(iv = qFiles.begin(); iv != qFiles.end(); ++iv){
        qDebug(qPrintable((*iv)->fileName() + " destruct"));
        delete *iv;
    }
}

调用

void mainWindow::getUnstartedCourseList()
{
    QMap<QString, QString> param2;
    param2.insert("userID","112212334");
    param2.insert("userToken","VpFHzUv25L75KXeTqpiPi7alRKMGbvbR");
    QMap<QString, QString> param3;
    param3.insert("profile_image","E:/jab8fc3f078f027197484aa4cb30b9505");
    SC_HttpClient::postWithFile("request_url", param2, param3);
    //关心返回结果的话,就不要postWithFile定义为static函数,可以定义成普通成员函数,然后在调用的class中实现信号和槽接受返回结果
}

如果关心返回结果的话,可以将QEventLoop的connect改为调用对象的信号和槽,

发布了275 篇原创文章 · 获赞 46 · 访问量 28万+

猜你喜欢

转载自blog.csdn.net/youyudexiaowangzi/article/details/101421963