如何使用 JSON 正文在 Qt 中发送 POST 请求
How to send a POST request in Qt with the JSON body
我正在尝试从 Qt 发送一个 POST 请求,请求正文为 JSON 格式。首先,我断言该请求适用于 curl:
curl -i -H "Content-Type: application/json" -d '{"key1": "value1", "key2": "value2"}' -X POST http://myserver.com/api
一切正常,我收到了来自服务器的预期响应。在 Python 中也是如此。现在我需要从 C++/Qt 发送这个请求:
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
QHttpMultiPart *httpMultiPart = new QHttpMultiPart(mgr);
QHttpPart *httpPart = new QHttpPart();
httpPart->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
httpPart->setBody("{\"key1\":\"value1\", \"key2\":\"value2\"}");
httpMultiPart->append(*httpPart);
QNetworkReply *reply = mgr->post(QNetworkRequest(QUrl("http://myserver.com/api")), httpMultiPart);
QObject::connect(reply, &QNetworkReply::finished, [=]()
{
QString err = reply->errorString();
QString contents = QString::fromUtf8(reply->readAll());
});
现在我收到一个错误,其中 errorString returns: `
"Error downloading http://myserver.com/api - server replied: Unsupported Media Type"`
可能是什么原因?我应该如何发送 POST 请求,就像我用 curl 发送的请求一样?
QHttpMultiPart 用于发送 MIME 多部分消息,但在这种情况下不需要发送该类型的信息。相反,您应该使用 QJsonDocument 创建 json 并将其转换为 QByteArray:
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
const QUrl url(QStringLiteral("http://myserver.com/api"));
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QJsonObject obj;
obj["key1"] = "value1";
obj["key2"] = "value2";
QJsonDocument doc(obj);
QByteArray data = doc.toJson();
// or
// QByteArray data("{\"key1\":\"value1\",\"key2\":\"value2\"}");
QNetworkReply *reply = mgr->post(request, data);
QObject::connect(reply, &QNetworkReply::finished, [=](){
if(reply->error() == QNetworkReply::NoError){
QString contents = QString::fromUtf8(reply->readAll());
qDebug() << contents;
}
else{
QString err = reply->errorString();
qDebug() << err;
}
reply->deleteLater();
});
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
QUrl url = QUrl("http://myserver.com/api");
QJsonObject param;
param.insert("key1", QJsonValue::fromVariant("value1"));
param.insert("key2", QJsonValue::fromVariant("value2"));
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkReply* reply = mgr->post(request, QJsonDocument(param).toJson(QJsonDocument::Compact));
/*Реализуем ожидание конца загрузки с таймаутом*/
QTimer timer;
timer.setSingleShot(true);
QEventLoop loop;
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
timer.start(10000); // 10 secs. timeout
loop.exec();
if(timer.isActive())
{
timer.stop();
if(reply->error() == QNetworkReply::NoError)
{
// Success
QByteArray buffer = reply->readAll();
qDebug()<<buffer;
}
else
{
// handle error
QString error = reply->errorString();
qDebug()<< "reply->errorString() " << error;
}
}
else
{
disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
reply->abort();
}
reply->deleteLater();
我正在尝试从 Qt 发送一个 POST 请求,请求正文为 JSON 格式。首先,我断言该请求适用于 curl:
curl -i -H "Content-Type: application/json" -d '{"key1": "value1", "key2": "value2"}' -X POST http://myserver.com/api
一切正常,我收到了来自服务器的预期响应。在 Python 中也是如此。现在我需要从 C++/Qt 发送这个请求:
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
QHttpMultiPart *httpMultiPart = new QHttpMultiPart(mgr);
QHttpPart *httpPart = new QHttpPart();
httpPart->setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));
httpPart->setBody("{\"key1\":\"value1\", \"key2\":\"value2\"}");
httpMultiPart->append(*httpPart);
QNetworkReply *reply = mgr->post(QNetworkRequest(QUrl("http://myserver.com/api")), httpMultiPart);
QObject::connect(reply, &QNetworkReply::finished, [=]()
{
QString err = reply->errorString();
QString contents = QString::fromUtf8(reply->readAll());
});
现在我收到一个错误,其中 errorString returns: `
"Error downloading http://myserver.com/api - server replied: Unsupported Media Type"`
可能是什么原因?我应该如何发送 POST 请求,就像我用 curl 发送的请求一样?
QHttpMultiPart 用于发送 MIME 多部分消息,但在这种情况下不需要发送该类型的信息。相反,您应该使用 QJsonDocument 创建 json 并将其转换为 QByteArray:
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
const QUrl url(QStringLiteral("http://myserver.com/api"));
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
QJsonObject obj;
obj["key1"] = "value1";
obj["key2"] = "value2";
QJsonDocument doc(obj);
QByteArray data = doc.toJson();
// or
// QByteArray data("{\"key1\":\"value1\",\"key2\":\"value2\"}");
QNetworkReply *reply = mgr->post(request, data);
QObject::connect(reply, &QNetworkReply::finished, [=](){
if(reply->error() == QNetworkReply::NoError){
QString contents = QString::fromUtf8(reply->readAll());
qDebug() << contents;
}
else{
QString err = reply->errorString();
qDebug() << err;
}
reply->deleteLater();
});
QNetworkAccessManager *mgr = new QNetworkAccessManager(this);
QUrl url = QUrl("http://myserver.com/api");
QJsonObject param;
param.insert("key1", QJsonValue::fromVariant("value1"));
param.insert("key2", QJsonValue::fromVariant("value2"));
QNetworkRequest request(url);
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
QNetworkReply* reply = mgr->post(request, QJsonDocument(param).toJson(QJsonDocument::Compact));
/*Реализуем ожидание конца загрузки с таймаутом*/
QTimer timer;
timer.setSingleShot(true);
QEventLoop loop;
connect(&timer, SIGNAL(timeout()), &loop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
timer.start(10000); // 10 secs. timeout
loop.exec();
if(timer.isActive())
{
timer.stop();
if(reply->error() == QNetworkReply::NoError)
{
// Success
QByteArray buffer = reply->readAll();
qDebug()<<buffer;
}
else
{
// handle error
QString error = reply->errorString();
qDebug()<< "reply->errorString() " << error;
}
}
else
{
disconnect(reply, SIGNAL(finished()), &loop, SLOT(quit()));
reply->abort();
}
reply->deleteLater();