QNetworkAccessManager的post接口可以接收多种参数,一般使用QByteArray发送普通文本请求,如果要带文件内容做参数,就需要用到QHttpMultiPart类型的参数,封装formData
这里定义的是一个static成员函数
static void postWithFile(const QString url, QMap<QString, QString> ¶ms, QMap<QString, QString> &files);
实现
void SC_HttpClient::postWithFile(const QString url, QMap<QString, QString> ¶ms, 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改为调用对象的信号和槽,