Qt之QHttpMultiPart(上传文件到微信小程序云服务器)

6 篇文章 1 订阅

简介

网页的form表单中,如果存在上传文件的表单,则需要将form标签设置enctype="multipart/form-data"属性,意思是将Content-Type设置成multipart/form-data,multipart 类型对发送非文本类型非常有用。Qt中对应为QHttpMultiPart、QHttpPart,QHttpMultiPart 类似于一个 RFC 2046 所描述的 MIME multipart 消息,通过 HTTP 发送,常用于传输较大的文件数据。

enum QHttpMultiPart::ContentType

Constant 常数Value 价值Description 描述
QHttpMultiPart::MixedType0对应于"multipart/mixed"子类型,意味着主体部件彼此独立,如RFC 2046中所述。
QHttpMultiPart::RelatedType1对应于"multipart/related"子类型,意味着主体部件彼此相关,如RFC 2387中所述。
QHttpMultiPart::FormDataType2对应于“multipart/form-data”子类型,这意味着主体部分包含表单元素,如RFC 2388中所述。
QHttpMultiPart::AlternativeType3对应于"multipart/alternative"子类型,这意味着主体部分是相同信息的可选表示,如RFC 2046中所述。

下面我们看下微信小程序云服务器中关于上传文件的规定:

上传链接使用说明

用户获取到返回数据后,需拼装一个 HTTP POST 请求,其中 url 为返回包的 url 字段,Body 部分格式为 multipart/form-data,具体内容如下:

keyvalue说明
keythis/is/a/example/file.path请求包中的 path 字段
Signatureq-sign-algorithm=sha1&q-ak=AKID9...返回数据的 authorization 字段
x-cos-security-tokenCukha70zkXIBqkh1Oh...返回数据的 token 字段
x-cos-meta-fileidHDze32/qZENCwWi5...返回数据的 cos_file_id 字段
file文件内容文件的二进制内容

其中HttpPart部分的key、Signature、x-cos-security-token、x-cos-meta-fileid均由请求地址返回数据获得。:

POST https://api.weixin.qq.com/tcb/uploadfile?access_token=ACCESS_TOKEN

知道了上传文件的方法,现在我们开始撸起袖子加油干吧!

此处重点说明下:

文档中说我们不需要指定boundary,它也是会自动给你添加boundary的,前提是必须保持MIME中的boundary和请求头里的boundary值一致,因此需要添加请求头中的boundary,否则传不了,如果自定义boundary,也需要和请求头中的保持一致!(官方文档中的说法存在一定的问题)

QNetworkRequest mulRequest;
mulRequest.setHeader(QNetworkRequest::ContentTypeHeader,"multipart/form-data;boundary=boundary_.oOo._");

上传的表单中的Body部分,使用QHttpPart对每个需要上传的字段进行设置,QHttpPart 类拥有一个 body 部位,用于 HTTP multipart MIME消息中(由 QHttpMultiPart 表示)。一个 QHttpPart 由一个 header 块和数据块组成,彼此之间存在两个连续换行。要设置 headers,使用 setHeader() 和 setRawHeader(),对于读取小数据块,使用 setBody();如果是更大数据块,例如:图像,使用 setBodyDevice()。下面看看上传文件名为“3.png”的图片至小程序云服务器的代码段:

void JsonDataModel::sendFileData(QString path,QString url,QString authorization,QString token,QString cos_file_id){//此处为获取到的body数据,待上传用
    QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QNetworkRequest mulRequest;
    mulRequest.setHeader(QNetworkRequest::ContentTypeHeader,"multipart/form-data;boundary=boundary_.oOo._");//此处boundary不能省!需要和QHttpMultiPart中的一致

    QString fileName = QFileDialog::getOpenFileName(0,
                       tr("选择图片"),QDir::currentPath(), tr("Image Files (*.png *.jpg *.bmp)"));//选择3.png的路径
    QFile *file = new QFile(fileName,multiPart);//开辟新的储存空间给文件,当释放multiPart空间时同时释放文件空间
    file->open(QIODevice::ReadOnly);

    QHttpPart keyPart;
    keyPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"key\""));
    keyPart.setBody(path.toUtf8());

    QHttpPart authorizationPart;
    authorizationPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"Signature\""));
    authorizationPart.setBody(authorization.toUtf8());

    QHttpPart tokenPart;
    tokenPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"x-cos-security-token\""));
    tokenPart.setBody(token.toUtf8());

    QHttpPart filePart;
    filePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"x-cos-meta-fileid\""));
    filePart.setBody(cos_file_id.toUtf8());

    QHttpPart imagePart;
    imagePart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/png"));
    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data;name=\"file\""));
//    imagePart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data;name=\"file\";filename=\"3.png\"")); 部分服务器可能需要添加filename字段,小程序云服务器不需要此字段   
    imagePart.setBodyDevice(file);

    multiPart->append(keyPart);
    multiPart->append(authorizationPart);
    multiPart->append(tokenPart);
    multiPart->append(filePart);
    multiPart->append(imagePart);

    QUrl u(url);
    mulRequest.setUrl(u);
    QNetworkReply *r = manager->post(mulRequest, multiPart);
    connect(r,SIGNAL(finished()),this,SLOT(slotSendFileData()));
    multiPart->setParent(r); // delete the multiPart with the reply防止内存泄漏,在槽函数中释放

}

上传后图片在小程序云开发控制台中查看:

 

 

 

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵喵叫的猴

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值