Qt中使用QHttpMultiPart调用FaceCloud REST API发送图片请求出错排查
问题描述
我想用C++ Qt编写的测试客户端,通过REST API把图片发送到FaceCloud以获取图片相关信息。我按照文档写了POST请求代码(用QHttpMultiPart和QNetworkReply),但一直没法正常工作。这是我第一次接触REST API,以下是我的代码,请问哪里出错了?
QUrl testUrl("https://backend.facecloud.tevian.ru/api/v1/photos"); QNetworkRequest request(testUrl); //auth token i've got before request.setRawHeader(QByteArray("Authorization"), token.toUtf8()); QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart firstPart; const QString header = "application/json"; firstPart.setHeader(QNetworkRequest::ContentTypeHeader, header); QJsonObject req; QJsonDocument doc; QByteArray data; req.insert("fd_min_size",0); req.insert("fd_max_size",0); req.insert("fd_threshold",0.8); req.insert("rotate_until_faces_found",true); req.insert("orientation_classifier",true); QJsonArray array; array.push_back("0"); array.push_back("0"); array.push_back("1000"); array.push_back("1000"); req.insert("face", array); req.insert("person_id",1); doc = QJsonDocument(req); data = doc.toJson(); firstPart.setBody(data); QString img_path = "C:/Users/brode/Downloads/hi.jpg"; QString img_name = "hi.jpg"; QHttpPart secondPart; secondPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("image/jpeg")); secondPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"preview_file\"; filename=\""+ img_name+ "\"")); QFile *file = new QFile(img_path); if (!file->exists()) { return; } file->open(QIODevice::ReadOnly); secondPart.setBodyDevice(file); file->setParent(multiPart); // we cannot delete the file now, so delete it with the multiPart multiPart->append(firstPart); multiPart->append(secondPart); QNetworkReply* reply = manager.post(request, multiPart); multiPart->setParent(reply); // delete the multiPart with the reply connect(reply, &QNetworkReply::readyRead,this, &rest_handler::readyRead);
问题排查与修复
以下是你代码里的几个关键问题,逐一修正后应该能正常工作:
1. Authorization头格式错误
REST API的Authorization头通常需要带上认证类型(比如Bearer),直接传token服务端无法识别正确的认证方式。修改为:
request.setRawHeader(QByteArray("Authorization"), QString("Bearer %1").arg(token).toUtf8());
2. 第一个表单部分缺少Content-Disposition头
你创建的JSON参数部分没有设置Content-Disposition头,服务端无法识别该表单字段的名称。根据FaceCloud API定义,这个JSON参数对应的字段名应为meta,需添加:
firstPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"meta\""));
3. face数组元素类型错误
你给face数组插入的是字符串类型值,但API要求的是整数类型。修改数组元素为整数:
QJsonArray array; array.push_back(0); array.push_back(0); array.push_back(1000); array.push_back(1000);
4. person_id类型可能不匹配
如果API要求person_id为字符串类型(而非整数),需将其转换为字符串:
req.insert("person_id", QString::number(1));
若API明确支持整数类型,此部分可保留,但建议先确认文档参数定义。
5. 缺少错误处理逻辑
你仅连接了readyRead信号,未处理请求失败场景(如网络错误、HTTP状态码异常)。建议补充错误处理:
connect(reply, &QNetworkReply::errorOccurred, this, [=](QNetworkReply::NetworkError code) { qDebug() << "请求错误:" << code << reply->errorString(); }); connect(reply, &QNetworkReply::finished, this, [=]() { qDebug() << "HTTP状态码:" << reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt(); reply->deleteLater(); });
6. 确认QNetworkManager实例有效
确保manager是有效的QNetworkManager实例(比如作为类成员变量存在,而非局部临时变量),避免因对象提前销毁导致请求异常。
内容的提问来源于stack exchange,提问作者Максим
相关产品推荐
相关产品推荐

