Qt提交POST表单调用法国地址API返回400错误该如何解决
问题原因
你使用的QNetworkAccessManager::post直接传入拼接字符串的方式,对应的是application/x-www-form-urlencoded格式的普通表单提交,而你参考的curl命令中-F参数对应的是multipart/form-data格式的文件上传表单,两种格式不兼容,因此服务器无法识别你提交的CSV文件,返回400错误。
正确实现步骤
你需要使用Qt提供的QHttpMultiPart和QHttpPart类构造符合要求的文件上传表单,具体实现代码如下:
#include <QCoreApplication> #include <QNetworkAccessManager> #include <QNetworkRequest> #include <QNetworkReply> #include <QFile> #include <QHttpMultiPart> #include <QHttpPart> #include <iostream> int main (int argc, char* argv[]){ QCoreApplication app(argc, argv); QNetworkAccessManager man; QUrl url("https://api-adresse.data.gouv.fr/search/csv/"); QNetworkRequest req(url); QFile inputFile("<path_to_search.csv>"); // 先判断文件是否打开成功,避免提交空内容 if (!inputFile.open(QIODevice::ReadOnly)) { std::cerr << "无法打开CSV文件" << std::endl; return 1; } // 构造multipart/form-data类型的表单 QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType); QHttpPart dataPart; // 设置表单字段属性,对应curl -F data=@文件的参数 dataPart.setHeader(QNetworkRequest::ContentDispositionHeader, QVariant("form-data; name=\"data\"; filename=\"search.csv\"")); // 写入CSV文件内容 dataPart.setBody(inputFile.readAll()); multiPart->append(dataPart); QNetworkReply* reply = man.post(req, multiPart); // 将multiPart的生命周期绑定到reply,reply销毁时自动销毁multiPart避免内存泄漏 multiPart->setParent(reply); QObject::connect(reply, &QNetworkReply::finished, [&](){ if (reply->error() != QNetworkReply::NoError) { std::cerr << "请求错误: " << reply->errorString().toStdString() << std::endl; } else { QByteArray read = reply->readAll(); std::cout << "Reading Data:" << std::endl; std::cout << read.toStdString() << std::endl; } reply->close(); reply->deleteLater(); app.quit(); }); return app.exec(); }
注意事项
- 不需要手动给请求设置
Content-Type头,QNetworkRequest会自动根据QHttpMultiPart生成带边界标识的正确请求头 - CSV文件需要符合法国地址API的格式要求,首行至少包含地址字段列
- 生产环境使用建议增加超时处理逻辑,避免请求卡住
内容的提问来源于stack exchange,提问作者Angela Riley
相关产品推荐
相关产品推荐

