在使用QT通过HTTP与服务器交互时,有时得模拟浏览器进行提交数据,提交的方式有多种,如:raw
与 form-data
等,而这两者都属于body
字段当中的一种数据形式,此外body中还有x-www-form-urlencoded
、binary
和GraphQL
。
raw
可以上次任何格式的文件,如:text、json、xml、html等,本文的例子就是使用raw
POST JSON数据;form-data
主要是表单数据,键值对。这里键值对数据不拼凑在API之后。也有写成multipart/form-data
,它可以包含文件和键值对,当上传的字段是文件时,要用Content-Type来说明文件的类型。x-www-form-urlencoded
类似于form-data
,数据也是以键值对形式存在,但不同的是,它是将数据直接拼凑在API之后,
下图是 Postman 模拟提交的截图,本文以raw
方式提交JSON
数据为例:
提交数据为:
{
"password": "25d55ad283aa400af4*************", //MD5校验之后的密码
"username": "test2"
}
发送部分参考代码:
//初始化设置省略...
//组装JSON数据
QJsonObject login_json;
login_json.insert("username", user_name);
login_json.insert("password", md5(user_passwd));
QJsonDocument doc;
doc.setObject(login_json);
QByteArray post_loginArray = doc.toJson(QJsonDocument::Compact);
//登陆链接
QNetworkReply* login = m_accessManager_Registered->post(request_registered,post_loginArray);
如上图 Postman 截图所示,服务器返回的是一个JSON对象,我们需要在QT中解析JSON 对象,获取登陆的token
值。
解析部分参考代码:
//用户登陆响应槽
void MainWindow::login_Registered(QNetworkReply *login)
{
if (login->error() == QNetworkReply::NoError)
{
// 获取响应信息
QByteArray bytes = login->readAll(); //读取所有字节;
QJsonParseError jsonError_login;
//转化为JSON文档
QJsonDocument doucment = QJsonDocument::fromJson(bytes, &jsonError_login);
// 解析Json error
if (doucment.isObject())
{
QJsonObject obj = doucment.object();
QJsonValue val;
QJsonValue data_value;
if (obj.contains("message")) {
QString succ_msg = obj.value("message").toString();
//ui->plainTextEdit->appendPlainText(tr("\n")+succ_msg);
qDebug() << tr("打印massage");
qDebug() << succ_msg;
}
if (obj.contains("code"))
{
val = obj.value("code");
if ((val.toInt()) == 0)
{
ui->plainTextEdit->appendPlainText("您已成功登陆账户\n");
QMessageBox::information(this, "成功","登陆成功!");
login_success = 1; //登陆状态——成功;
}
if (obj.contains("data"))
{
QJsonObject object_value = obj.value("data").toObject();
if(object_value.contains("token"))
{
token_val = object_value.value("token");
qDebug() << tr("打印token");
qDebug() << token_val;
}
if(object_value.contains("name")) //获取用户名;
{
username = QString(object_value.value("name").toString());
ui->plainTextEdit->appendPlainText(tr("登陆用户ID:") + username + tr(""));
qDebug() << tr("打印name");
qDebug() << username;
}
}
}
}
}
else
{
QMessageBox::information(this, "警告","登陆失败!");
qDebug()<<"handle errors here";
QVariant statusCodeV = login->attribute(QNetworkRequest::HttpStatusCodeAttribute);
//statusCodeV是HTTP服务器的相应码,reply->error()是Qt定义的错误码,可以参考QT的文档
ui->plainTextEdit->appendPlainText("\n found error ....code:" + statusCodeV.toInt());
qDebug( "found error ....code: %d %d\n", statusCodeV.toInt(), (int)login->error());
qDebug(qPrintable(login->errorString()));
}
login->deleteLater();
}
解析JSON部分会稍微复杂一点,但是只要结构清晰,代码实现上还是很容易的。对了,对于服务器token
校验,是每次请求都需要携带的,不然服务器会拒绝连接。
版权属于:编码书生
本文链接:https://codess.cc/archives/248.html
所有原创文章采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。
除特别注明,您可以自由的转载和修改,但请务必注明文章来源且不可用于商业目的。
7 条评论
[...]想了解Json解析的小伙伴们,先别走,获取Token以及快速上手Qt网络编程 另外关于Json数据类型及解析数组[...]
EW8HFO1 https://page.link
感谢
login_Registered和哪个信号连接呀,比如&QNetworkReply::readyRead、&QNetworkReply::downloadProgress、&QNetworkReply::finished
你好,抱歉现在才回复你。在Client没有进行上传或者下载操作时,单纯的post数据提交情况下,只连接`&QNetworkReply::finished`信号就可以,原理是:在Client post完之后,Server会返回HTTP/1.1 200 OK,QT 信号槽会自动触发QNetworkReply::finished,然后在finished函数中去解析返回的JSON 数据。完整的信号槽代码如下:
QObject::connect(m_accessManager_Registered, SIGNAL(finished(QNetworkReply*)), this, SLOT(login_Registered(QNetworkReply*)));
楼主,request_registered这个QHttpRequest 具体是这设置得哇?
抱歉现在才回复你。这是声明了一个请求类,它包含通过网络请求所必需的信息的类,比如请求头、服务器地址、缓存信息、接受类型、时间格式等等...详情请参阅官方文档:https://doc.qt.io/archives/qt-4.8/qnetworkrequest.html#details