概念不再叙述,直接上代码,demo有下载链接
Base64方式:
这种方式是获取图片的流数据,然后通过QUrlQuery传送过去,需要注意:
base64中,加号(+)是base64编码的一部分,如果将+号转变为空格,就会导致解密失败。
现在应该很清楚为什么base64后,通过http请求后,数据丢失的原因了吧。
1、Base64加密后的数据:
gLi5lSf1FW+r1nuhjheOlA2vYlbt1U9kOKnGPPG/LZU+J7qlqUSckCtGfRiQkkqgfZHwEGaBZkpGWuIyZ+tCegU8xj85Xp7bG3Fyfd6k=
在对Base64加密进行http传输时,后台收到的数据会出现空格的现象。如下
gLi5lSf1FW r1nuhjheOlA2vYlbt1U9kOKnGPPG/LZU J7qlqUSckCtGfRiQkkqgfZHwEGaBZkpGWuIyZ tCegU8xj85Xp7bG3Fyfd6k=
这就导致传输的数据和接收的数据不一致,导致解密失败
一般情况下,URL 中的参数应使用 url 编码规则,即把参数字符串中除了 -_. 之外的所有非字母数字字符都将被替换成百分号(%)后跟两位十六进制数,空格则编码为加号(+)。
base64 编码中使用了加号(+),而 + 在 URL 传递时会被当成空格,因此必须要将 base64 编码后的字符串中的加号替换成 %2B 才能当作 URL 参数进行传递。否则在服务器端解码后就会出错。
因为ajax在传输过程中加号会变成空格而base64里是有加号的,所以在ajax传输前先要对base64进行编码,把加号替换成%2B的url编码。
所以下面的例子有一句: QByteArray t = img64.replace("+","%2B");
QNetworkRequest request;
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded;charset=utf-8");
QString baseUrl = "https://fsearch-docker.suanshubang.com/search/api/picsearch";
QUrl url(baseUrl);
request.setUrl(url);
QImage img("C:/wmm/test/postTest/post/test4.png");
QByteArray ba;
QBuffer buf(&ba);
img.save(&buf,"PNG");
QByteArray img64 = ba.toBase64();
//注意替换
QByteArray t = img64.replace("+","%2B");
QUrlQuery postPicData;
postPicData.addQueryItem("cuid", "945351B4F1DC69BDFC87C92318BC6EFE|0");
postPicData.addQueryItem("product", "XYJPena");
postPicData.addQueryItem("token", "918dcd362db5e2a83577f87eb7866d75");
postPicData.addQueryItem("imageWidth", QString("%1").arg(152));
postPicData.addQueryItem("imageHeight", QString("%1").arg(24));
postPicData.addQueryItem("imageData", t);
QNetworkAccessManager* networkManager = new QNetworkAccessManager(this);
connect(networkManager, SIGNAL(finished(QNetworkReply *)), this, SLOT(replyFinished(QNetworkReply *)));
networkManager->post(request, postPicData.toString(QUrl::FullyEncoded).toUtf8());
file方式:
注意事项:
1 建议当传输完成后,主动将file文件close;
2 multiPart->setBoundary("—wmm—") 设置自己的分隔符
QUrl url("iot-server/api/pen/device/wrongbook/add");
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
QHttpPart textPart;
QString filename = "C:/wmm/test/postTest/post/test4.png";
//stamp
textPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"stamp\""));
textPart.setBody("your para stamp");
multiPart->append(textPart);
QFile *file = new QFile(filename);
if (file->open(QIODevice::ReadOnly))
{
QHttpPart filePart;
filePart.setHeader(QNetworkRequest::ContentDispositionHeader,
QString("form-data; name=\"file\"; filename=\"%1\"").arg(filename));
filePart.setBodyDevice(file);
file->setParent(multiPart); // file deleted on the destruction of multiPart
multiPart->append(filePart);
}
else {
qDebug() << filename << "ultiPart->append(filePart) open failed";
}
multiPart->setBoundary("---wmm---"); //设置分隔符
QNetworkAccessManager netManager;
QNetworkRequest request(url);
QNetworkReply *pNetworkResponse = netManager.post(request,multiPart);
multiPart->setParent(pNetworkResponse);
QObject::connect(pNetworkResponse, &QNetworkReply::finished, [=]{
file.close();
QByteArray res = pNetworkResponse->readAll();
QJsonObject json_object = QJsonDocument::fromJson(res).object();
pNetworkResponse->deleteLater();
}
}