Correct format for HTTP POST using QNetworkRequest
This is not the right way to write your HTTP request. The following piece of code is more correct :
connect(m_qnam, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleNetworkData(QNetworkReply*)));
connect(m_qnam,SIGNAL(sslErrors(QNetworkReply*,QList<QSslError>)), this, SLOT(handleSSLErrors(QNetworkReply*)));
// Build your JSON string as usual
QByteArray jsonString = "{\"method\":\"AuthenticatePlain\",\"loginName\":\"username@domain.com\",\"password\":\"mypass\"}";
// For your "Content-Length" header
QByteArray postDataSize = QByteArray::number(jsonString.size());
// Time for building your request
QUrl serviceURL("https://www.superService.com/api/1.7/ssapi.asmx");
QNetworkRequest request(serviceURL);
// Add the headers specifying their names and their values with the following method : void QNetworkRequest::setRawHeader(const QByteArray & headerName, const QByteArray & headerValue);
request.setRawHeader("User-Agent", "My app name v0.1");
request.setRawHeader("X-Custom-User-Agent", "My app name v0.1");
request.setRawHeader("Content-Type", "application/json");
request.setRawHeader("Content-Length", postDataSize);
// Use QNetworkReply * QNetworkAccessManager::post(const QNetworkRequest & request, const QByteArray & data); to send your request. Qt will rearrange everything correctly.
QNetworkReply * reply = m_qnam->post(request, jsonString);
How can I POST data to a url using QNetworkAccessManager
I used:
QByteArray postData;
postData.append("param1=string&");
postData.append("param2=string");
So & instead of newline after each parameter.
HTTP POST request in QT using QNetworkAccessManager
It seems that you do not know the following concepts:
Qt Network like all Qt modules work asynchronously so don't think about getting the information synchronously.
Qt needs an eventloop, in this case QCoreApplication is enough.
If you want to do periodic tasks then you should use a QTimer instead of a while loop with Sleep.
Considering the above, the solution is:
httpmanager.h
#ifndef HTTPMANAGER_H
#define HTTPMANAGER_H
#include <QObject>
class QNetworkReply;
class QNetworkAccessManager;
class HTTPManager : public QObject
{
Q_OBJECT
public:
HTTPManager(QObject *parent=nullptr);
~HTTPManager();
void postData(QString str);
private Q_SLOTS:
void replyFinished(QNetworkReply *rep);
private:
QNetworkAccessManager * manager;
QNetworkReply *reply;
};
#endif // HTTPMANAGER_H
httpmanager.cpp
#include "httpmanager.h"
#include <QNetworkAccessManager>
#include <QNetworkReply>
HTTPManager::HTTPManager(QObject *parent)
: QObject(parent), manager(new QNetworkAccessManager(this))
{
connect(manager, &QNetworkAccessManager::finished,this, &HTTPManager::replyFinished);
}
HTTPManager::~HTTPManager()
{
}
void HTTPManager::postData(QString str)
{
QNetworkRequest request;
QByteArray data = str.toUtf8();
QUrl url;
url.setScheme("http");
url.setHost("test.vivcorefmms.com");
url.setPath("/node/filter_data");
request.setUrl(url);
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
manager->post(request, data);
}
void HTTPManager::replyFinished(QNetworkReply *rep)
{
QByteArray bts = rep->readAll();
QString str = QString::fromUtf8(bts);
qDebug().noquote() << "Reply:"<<str;
rep->deleteLater();
}
main.cpp
#include "httpmanager.h"
#include <QCoreApplication>
#include <QTimer>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
HTTPManager manager;
QTimer timer;
timer.setInterval(1000);
QObject::connect(&timer, &QTimer::timeout, [&manager](){
manager.postData("A==##1802201049565471101000000N0526.874000E07256.4380000101035070#&11397002170466466466466466&12208004230370336441514488!~~~0");
});
timer.start();
return a.exec();
}
Reply: <head><title>Not Acceptable!</title></head><body><h1>Not Acceptable!</h1><p>An appropriate representation of the requested resource could not be found on this server. This error was generated by Mod_Security.</p></body></html>
And that is caused because a user-agent is missing so modifying it to:
request.setRawHeader("Content-Type", "application/x-www-form-urlencoded");
request.setRawHeader("User-Agent", "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/35.0.1916.47 Safari/537.36");
manager->post(request, data);
Obtaining the following:
Reply: <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Database Error</title>
<style type="text/css">
::selection { background-color: #E13300; color: white; }
::-moz-selection { background-color: #E13300; color: white; }
body {
background-color: #fff;
margin: 40px;
font: 13px/20px normal Helvetica, Arial, sans-serif;
color: #4F5155;
}
a {
color: #003399;
background-color: transparent;
font-weight: normal;
}
h1 {
color: #444;
background-color: transparent;
border-bottom: 1px solid #D0D0D0;
font-size: 19px;
font-weight: normal;
margin: 0 0 14px 0;
padding: 14px 15px 10px 15px;
}
code {
font-family: Consolas, Monaco, Courier New, Courier, monospace;
font-size: 12px;
background-color: #f9f9f9;
border: 1px solid #D0D0D0;
color: #002166;
display: block;
margin: 14px 0 14px 0;
padding: 12px 10px 12px 10px;
}
#container {
margin: 10px;
border: 1px solid #D0D0D0;
box-shadow: 0 0 8px #D0D0D0;
}
p {
margin: 12px 15px 12px 15px;
}
</style>
</head>
<body>
<div id="container">
<h1>A Database Error Occurred</h1>
<p>Error Number: 1048</p><p>Column 'node_id' cannot be null</p><p>INSERT INTO `node_info` (`node_info_id`, `node_id`, `message_id`, `gsm`, `wifi`, `gprs`, `_3g`, `bluetooth`, `gps`, `emergency_code`, `env_temperature`, `env_humidity`, `env_pressure`, `gps_speed`, `gps_latitude`, `gps_longitude`, `date`, `time`, `number_of_compartment`, `number_of_dispense`, `sys_date`, `sys_time`) VALUES ('', NULL, '654', '7', '0', '1', '1', '1', '0', '0', '03', '507', '0101', '0', NULL, NULL, '#18022', '010495', 15, '', '2020-03-28', '23:31:10')</p><p>Filename: models/Model_master.php</p><p>Line Number: 156</p> </div>
</body>
</html>
And the message points out the error:
Error Number: 1048
Column 'node_id' cannot be null
INSERT INTO `node_info` (`node_info_id`, `node_id`, `message_id`, `gsm`, `wifi`, `gprs`, `_3g`, `bluetooth`, `gps`, `emergency_code`, `env_temperature`, `env_humidity`, `env_pressure`, `gps_speed`, `gps_latitude`, `gps_longitude`, `date`, `time`, `number_of_compartment`, `number_of_dispense`, `sys_date`, `sys_time`) VALUES ('', NULL, '654', '7', '0', '1', '1', '1', '0', '0', '03', '507', '0101', '0', NULL, NULL, '#18022', '010495', 15, '', '2020-03-28', '23:18:26')
Filename: models/Model_master.php
Line Number: 156
Which shows an error caused by the data sent that seems not to comply with the processing, that is, A==##1802201049565471101000000N0526.874000E07256.4380000101035070#&11397002170466466466466466&12208004230370336441514488!~~~0
that seems to be not well formed
How do I send payload via a QNetworkAccessManager for post?
I found this
Correct format for HTTP POST using QNetworkRequest
QByteArray jsonString = "{\"method\":\"AuthenticatePlain\",\"loginName\":\"username@domain.com\",\"password\":\"mypass\"}";
QNetworkReply * reply = m_qnam->post(request, jsonString);
Send POST via Qt shrink the post content
The issue was coming from the sent data : I was sending chars that was interpreted as querys like =
or &
.
I just remove its from the string using this :
content.remove("[=|&]");
and it worked well.
How to send a POST request in Qt with the JSON body
QHttpMultiPart is used to send MIME multipart message but in this case it is not required to send that type of information. Instead, you should use QJsonDocument to create the json and convert it to 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();
});
Make HTTP POST request with a list of named parameters in Qt
QUrl params;
params.addQueryItem("key1", "value1");
params.addQueryItem("key2", "value2");
QUrl resource("http://server.com/form.php");
QNetworkAccessManager* manager = new QNetworkAccessManager(this);
connect(manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleEndOfRequest(QNetworkReply*)));
QNetworkRequest request(resource);
//Force Content-Type header
request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
manager->post(request, params.encodedQuery());
This code assumes that your current object is a QObject (passed as a parent for QNeworkAccessManager and slots declaration)
Qt Simple Post Request
Connect the QNetworkAccessManager signal finished to your slot and using QNetworkReply you should read all the contents of the webpage.
Here is a get example it can be easily adapted for the post method.
void MainWindow::on_pushButton_clicked()
{
QNetworkAccessManager * mgr = new QNetworkAccessManager(this);
connect(mgr,SIGNAL(finished(QNetworkReply*)),this,SLOT(onfinish(QNetworkReply*)));
connect(mgr,SIGNAL(finished(QNetworkReply*)),mgr,SLOT(deleteLater()));
mgr->get(QNetworkRequest(QUrl("http://www.google.com")));
}
void MainWindow::onfinish(QNetworkReply *rep)
{
QByteArray bts = rep->readAll();
QString str(bts);
QMessageBox::information(this,"sal",str,"ok");
}
Http POST, selecting the page using Qt
The line
url_str = "/page_wanted?parameters=5&t=3";
is missing a plus sign :D try
url_str += "/page_wanted?parameters=5&t=3";
and you should be good to go...
How do I write a Qt HTTP GET request?
You need three things:
QNetworkAccessManager * manager;
-> To send us a request.QNetworkRequest request;
-> what type of demand? get, post, ...QNetworkReply
. -> What's the answer?
for more detail:
http://doc.qt.io/qt-5/qnetworkaccessmanager.html#details
http://doc.qt.io/qt-5/qnetworkrequest.html#details
http://doc.qt.io/qt-5/qnetworkreply.html#details
for example:
.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
manager = new QNetworkAccessManager();
QObject::connect(manager, &QNetworkAccessManager::finished,
this, [=](QNetworkReply *reply) {
if (reply->error()) {
qDebug() << reply->errorString();
return;
}
QString answer = reply->readAll();
qDebug() << answer;
}
);
}
void MainWindow::on_pushButton_clicked()
{
request.setUrl(QUrl("http://url"));
manager->get(request);
}
MainWindow::~MainWindow()
{
delete ui;
delete manager;
}
.h file
private:
Ui::MainWindow *ui;
QNetworkAccessManager *manager;
QNetworkRequest request;
EDIT LAMBDA SLOT:
if not use lambda SIGNAL SLOT.
Discribe one slot in your .h file
for example:
private slots:
void managerFinished(QNetworkReply *reply);
in .cpp constructor replace lambda to
QObject::connect(manager, SIGNAL(finished(QNetworkReply*)),
this, SLOT(managerFinished(QNetworkReply*)));
now in your slot:
void MainWindow::managerFinished(QNetworkReply *reply) {
if (reply->error()) {
qDebug() << reply->errorString();
return;
}
QString answer = reply->readAll();
qDebug() << answer;
}
Related Topics
Why Is Iterating 2D Array Row Major Faster Than Column Major
Overload Resolution with Std::Function
Segmentation Fault with Char Array and Pointer in C on Linux
Incomplete Class Usage in Template
Speed Difference Between If-Else and Ternary Operator in C...
Why Can't I Access a Protected Member from an Instance of a Derived Class
Forward Declaration with Vector of Class Type - Pointer to Incomplete Class Type Not Allowed
Why Doesn't the C++11 'Auto' Keyword Work for Static Members
Open File with Fopen, Given Absolute Path on Windows
Best Practices for Recovering from a Segmentation Fault
Legality of Using Operator Delete on a Pointer Obtained from Placement New
Building Boost with Visual Studio 2013 (Express)
Why Is the Order of Evaluation for Function Parameters Unspecified in C++
Cuda Linking Error - Visual Express 2008 - Nvcc Fatal Due to (Null) Configuration File