笔记

  在使用QT通过HTTP与服务器交互时,有时得模拟浏览器进行提交数据,提交的方式有多种,如:rawform-data等,而这两者都属于body字段当中的一种数据形式,此外body中还有x-www-form-urlencodedbinaryGraphQL

  • 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"
}

post0184151.jpg

发送部分参考代码:

//初始化设置省略...

        //组装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校验,是每次请求都需要携带的,不然服务器会拒绝连接。

最后修改:2020 年 05 月 15 日
您的支持就是我持续更新的动力!