Post一个QT表格

Post a form with QT

我正在与一个使用 Qt 的 C++ 项目团队合作。作为我们项目的一部分,我们必须能够检索法国任何给定地址的坐标。法国政府提供了一个 API 来为我们处理这个问题。

对 API 的调用如下所示:

curl -X POST -F data=@path/to/file.csv https://api-adresse.data.gouv.fr/search/csv/

这是我写的代码:

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>");
    inputFile.open(QIODevice::ReadOnly);
    QByteArray data = inputFile.readAll();

    QNetworkReply* reply = man.post(req, "data=" + data);
    QObject::connect(reply, &QNetworkReply::finished, [&](){
            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();
}

服务器回复

{"code":400,"message":"A CSV file must be provided in data field"}

很明显我转发的表格不正确。我该如何进行?

要通过表单发送信息,我不知道查询部分,但你想使用 QHttpMultiPart,正如我在此 中展示的那样。适用于您的情况的解决方案是:

#include <QCoreApplication>
#include <QFile>
#include <QHttpMultiPart>
#include <QNetworkAccessManager>
#include <QNetworkReply>

QHttpMultiPart *buildMultpart(const QVariantMap & data, const QMap<QString, QString> filenames){

    QHttpMultiPart *multipart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
    QVariantMap::const_iterator i_data = data.constBegin();
    while (i_data != data.constEnd()) {
        QHttpPart postpart;
        postpart.setHeader(QNetworkRequest::ContentDispositionHeader, QString("form-data; name=\"%1\"").arg(i_data.key()));
        postpart.setBody(i_data.value().toByteArray());
        multipart->append(postpart);
        ++i_data;
    }
    QMap<QString, QString>::const_iterator i_filenames = filenames.constBegin();
    while (i_filenames != filenames.constEnd()) {

        QFile *file = new QFile(i_filenames.value());
        if(!file->open(QIODevice::ReadOnly)){
            delete  file;
            continue;
        }
        QHttpPart postpart;
        postpart.setHeader(QNetworkRequest::ContentDispositionHeader,
                           QString("form-data; name=\"%1\"; filename=\"%2\"")
                           .arg(i_filenames.key(), file->fileName()));
        postpart.setBodyDevice(file);
        multipart->append(postpart);
        file->setParent(multipart);
        ++i_filenames;
    }
    return multipart;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QNetworkAccessManager manager;

    QNetworkRequest request;
    QUrl url("https://api-adresse.data.gouv.fr/search/csv/");
    request.setUrl(url);
    QMap<QString, QString> filenames;
    filenames["data"] = "/path/of/file.csv";
    QHttpMultiPart *multipart = buildMultpart({}, filenames);
    QNetworkReply *reply = manager.post(request, multipart);
    multipart->setParent(reply);
    QObject::connect(reply, &QNetworkReply::finished, [reply](){
        if(reply->error() == QNetworkReply::NoError){
            qDebug().noquote() << reply->readAll();
        }
        else{
            qDebug() << reply->error() << reply->errorString();
        }
        reply->deleteLater();
        QCoreApplication::quit();
    });
    return a.exec();
}