QT 给http服务器发送GET/POST请求并接收返回值

简介: QT 给http服务器发送GET/POST请求并接收返回值

一、注意事项和重要代码


1、使用场景:qt,需要对服务器发送请求(包含报文),并接收服务器的返回值;服务器用的是mongoose模拟的服务器;


2、发送请求的方式有两种:GET和POST,两种方式的不同:Get将参数直接与网址整合为一个整体,而Post则将其拆为两个部分,一部分是网址,另一个部分才是参数,并且必须为其设置报文setHeader,否则服务器是无法找到参数的


本文主要介绍三种发送不同请求:


1)一种是GET方式请求,此时没有发送的报文,但是会有服务器返回值;


2)其余两种是POST请求,都有发送的报文,其中第一种发送的报文是一组json格式的数据(有返回信息);第二种是利用事件循环的方式发送一组json格式数据报文,因为在项目中都是有线程的,如果不利用事件循环进行阻塞,会导致请求无法发出。


三种具体方式见主要代码,最下方的详细代码实现的是get请求,如果想更改其他两种方式,更换startRequest函数即可,但是在使用post事件循环方式时,需要将.h中的startRequest定义更改为


    void startRequest(const QString &hostName,
                                 const QString &diskName,
                                 const QString &diskSize,
                                 const QString &mount,
                                 const QString &format,
                                 const QString &authStatus,
                                 const QString &keyfile);

在构造函数中调用时,改为

startRequest("2.3.4.5","dev/sda123","10G","/mnt","ext4","1","this is .key's content");


3、使用前提:一定要注意!!!!!,不然无法与服务器连接


在.pro文件中添加

QT += network

4、get主要代码

void MainWindow::startRequest(const QUrl &requestedUrl){
    url = requestedUrl;
    manager = new QNetworkAccessManager(this);
    req.setUrl(url);
    //由于请求发生重定向,所以要加上这行代码,设置自动跳转,否则会返回 302
    req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
    reply = manager->get(req);
    connect(reply,&QNetworkReply::finished,this,&MainWindow::replyFinished);
}

5、post第一种主要代码

void MainWindow::startRequest(const QUrl &requestedUrl){
    url = requestedUrl;
    //post
    QByteArray array;
    json.insert("table_operation","select");
    QJsonDocument document;
    document.setObject(json);
    array = document.toJson(QJsonDocument::Compact);
    qDebug()<<"array在转为json后为:"<<array;
    manager = new QNetworkAccessManager(this);
    req.setUrl(url);
    req.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json"));
    req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
    reply = manager->post(req,array);
    connect(reply,&QNetworkReply::finished,this,&MainWindow::replyFinished);
}

6、post第二种主要代码

void MainWindow::sendRequest(const QString &hostName,
                             const QString &diskName,
                             const QString &diskSize,
                             const QString &mount,
                             const QString &format,
                             const QString &authStatus,
                             const QString &keyfile)
{
    //1.json格式传输报文
    QJsonObject json;
    QJsonDocument jsonDoc;
    //打包json数据
    json["host_name"] = hostName;
    json["disk_name"] = diskName;
    json["disk_size"] = diskSize;
    json["mount"] = mount;
    json["format"] = format;
    json["certification_status"] = authStatus;
    json["keyfile_path"] = keyfile;
    jsonDoc.setObject(json);
    QByteArray dataArray = jsonDoc.toJson(QJsonDocument::Compact);
    qDebug()<< "jsondata组为:"<<dataArray;
    //2.构造URL&&请求头
    QString urlStr = "http://127.0.0.1:8000/test";
    qDebug()<<"url地址为:"<<urlStr;
    url = urlStr;
    //构造请求头
    req.setUrl(url);
    req.setHeader(QNetworkRequest::ContentTypeHeader,QVariant("application/json;charset=UTF-8"));
//    req.setRawHeader("Connection", "Keep-Alive");
    //3.post数据
    manager = new QNetworkAccessManager(this);
    reply = manager->post(req,dataArray);
    QEventLoop eventLoop;
    connect(manager,SIGNAL(finished(QNetworkReply*)),&eventLoop,SLOT(quit()));
    connect(reply,&QNetworkReply::finished,this,&MainWindow::replyFinished);
    eventLoop.exec();
}


二、话不多说上详细代码


QT创建一个继承QWidget的Qt Widgets Application就行


1、mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QDebug>
#include <QtNetwork>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QTextCodec>
#include <QFile>
#include <QTextStream>
#include <QDateTime>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    void startRequest(const QUrl &requestedUrl);
private:
    Ui::MainWindow *ui;
private:
    // [3] 添加对象
    QUrl url;
    QNetworkRequest req;
    QNetworkReply *reply;
    QNetworkAccessManager *manager;
private slots:
//    void startRequest(const QUrl &requestedUrl);
    void replyFinished();
};
#endif // MAINWINDOW_H


2、mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QLabel>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //调用函数发送请求,参数是请求的服务器地址
    startRequest( QUrl("http://127.0.0.1:8000/test"));
}
MainWindow::~MainWindow()
{
    delete ui;
}
void MainWindow::startRequest(const QUrl &requestedUrl){
    url = requestedUrl;
    manager = new QNetworkAccessManager(this);
    req.setUrl(url);
    //由于请求发生重定向,所以一定要加上这行代码,设置自动跳转,否则会返回 302
    req.setAttribute(QNetworkRequest::FollowRedirectsAttribute, true);
//    req.setRawHeader("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9");
//    req.setRawHeader("User-Agent","Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.198 Safari/537.36");
    //get方式发送请求
    reply = manager->get(req);
    //将服务器的返回信号与replyFinished槽连接起来,当服务器返回消息时,会在槽里做相应操作
    connect(reply,&QNetworkReply::finished,this,&MainWindow::replyFinished);
}
void MainWindow::replyFinished(){
    // <1>判断有没有错误
    if (reply->error()){
        qDebug()<<reply->errorString();
        reply->deleteLater();
        return;
    }
    // <2>检测网页返回状态码,常见是200,404等,200为成功
    int statusCode  = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
    qDebug() << "statusCode:" << statusCode;
    // <3>判断是否需要重定向
    if (statusCode >= 200 && statusCode <300){
        // ok
        // 准备读数据
        QTextCodec *codec = QTextCodec::codecForName("utf8");
        QString all = codec->toUnicode(reply->readAll());
        qDebug() << "接收到的数据" <<all;
        //显示在mainwindow 测试,将服务器返回值打印至label上,服务器用的是mongoose模拟
        QLabel *label = new QLabel(this);
        label->setText(all);
        label->move(200,200);
        label->setVisible(true);
        // 数据读取完成之后,清除reply
        reply->deleteLater();
        reply = nullptr;
    } else if (statusCode >=300 && statusCode <400){
        // redirect
        // 获取重定向信息
        const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
        // 检测是否需要重定向,如果不需要则读数据
        if (!redirectionTarget.isNull()) {
            const QUrl redirectedUrl = url.resolved(redirectionTarget.toUrl());
            reply->deleteLater();
            reply = nullptr;
            startRequest(redirectedUrl);
            qDebug()<< "http redirect to " << redirectedUrl.toString();
            return;
        }
    }
}

3、main.cpp

#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

这个项目的代码是get请求方式,如果要换成post,只需要将startRequest函数换成博客开头提到的【post主要代码】即可;


replyFinished函数是接收服务器返回的状态值和返回值的,可以自己做需要的操作。


三、结果图


1、服务器接收到的POST请求信息:


1.png1.png


2、GET请求没有发送报文,但是能收到mongoose模拟服务器的返回值:


1.png


四、参考


https://blog.csdn.net/china_jeffery/article/details/83246355


https://blog.csdn.net/qiufenpeng/article/details/81583768


https://www.cnblogs.com/cjdty/p/10659685.html


END


相关文章
|
24天前
|
XML 网络协议 Java
JavaWeb -- HTTP -- WEB服务器TOMCAT
JavaWeb -- HTTP -- WEB服务器TOMCAT
|
6天前
|
编解码 监控 网络协议
采用Qt+Live555搭建RTSP服务器
Live555是一个跨平台的流媒体开发库,支持多种流媒体协议,包括RTSP、SIP、RTP等,可以帮助我们快速实现视频流的传输和处理。
41 1
采用Qt+Live555搭建RTSP服务器
|
6天前
Qt http的认证方式以及简单实现
以上就是Qt实现HTTP认证的基本步骤。需要注意的是,以上代码未进行错误处理,实际使用时需要根据具体情况进行相应的错误处理。
5 1
|
18天前
|
Java 应用服务中间件 程序员
JavaWeb基础第四章(SpringBootWeb工程,HTTP协议与Web服务器-Tomcat)
JavaWeb基础第四章(SpringBootWeb工程,HTTP协议与Web服务器-Tomcat)
|
2月前
|
网络协议 数据格式 Python
Python进阶---HTTP协议和Web服务器
Python进阶---HTTP协议和Web服务器
29 4
|
2月前
|
自然语言处理 负载均衡 监控
处理HTTP请求的服务器
处理HTTP请求的服务器
41 1
|
1月前
|
JSON 安全 Java
JAVA Socket 实现HTTP与HTTPS客户端发送POST与GET方式请求
JAVA Socket 实现HTTP与HTTPS客户端发送POST与GET方式请求
27 0
|
10天前
|
安全 网络协议 网络安全
IP代理的三大协议:HTTP、HTTPS与SOCKS5的区别
**HTTP代理**适用于基本网页浏览,简单但不安全;**HTTPS代理**提供加密,适合保护隐私;**SOCKS5代理**灵活强大,支持TCP/UDP及认证,适用于绕过限制。选择代理协议应考虑安全、效率及匿名需求。
|
4天前
|
安全 算法 网络协议
HTTPS协议的详细讲解(四次握手)
HTTPS协议的详细讲解(四次握手)
|
1月前
|
安全 前端开发 中间件
中间件中HTTP/HTTPS 协议
【6月更文挑战第3天】
23 3

推荐镜像

更多