You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,提问作者Максим

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 06:54:25