【Qt】Qt 网络 | HTTP

文章目录

本文不涉及 HTTP 的相关前置知识,前置知识可参看
URL概念及组成
HTTP请求
HTTP响应及Cookie原理

HTTP Client

进行 Qt 开发时,和服务器之间的通信很多时候也会使用 HTTP 协议

  • 通过 HTTP 从服务器获取数据
  • 通过 HTTP 向服务器提交数据

因为 Qt 开发方向之一是图形化客户端开发,所以 Qt 只提供了客户端的 HTTP 通信,基本不使用 Qt 开发服务器

核心API

主要使用的类有三个,QNetworkAccessManagerQNetworkRequestQNetworkReply


QNetworkAccessManager

QNetworkAccessManager 提供了 HTTP客户端的 核心操作

例如:

API 说明
get(const QNetworkRequest& request) 发起一个 HTTP GET请求,返回值是 QNetworkReply 的对象指针。 主要用于从服务器获取数据
post(const QNetworkRequest& request, const QByteArray &data) 发起一个 HTTP POST 请求,返回 QNetworkReply 对象指针 主要用于向服务器提交/上传数据

HTTP 请求报文格式如下:

post请求中,data是要提交/上传的数据,QNetworkRequest 只表示一个 HTTP 请求(不包含请求体)

所以如果需要发送一个带有请求体的 HTTP请求,需要在 post 方法中通过单独的参数传入请求体数据


QNetworkRequest

QNetworkRequest 只表示一个 HTTP 请求(不包含请求体)

常用API:

API 说明
QNetworkRequest(const QUrl& url) 通过 URL 构造一个 HTTP 请求
setHeader(QNetworkRequest::KnownHeaders header, const QVariant &value) 设置请求头

QNetworkRequest::KnownHeaders

URL 的组成可参看 URL概念及组成

请求头都为 key-value 结构,QNetworkRequest::KnownHeaders 是一个枚举类型,用来表示请求头的 key,常用取值如下:

取值 说明
ContentTypeHeader 描述 请求体body类型
ContentLengthHeader 描述 请求体body长度
LocationHeader 用于重定向报文中指定重定向地址(响应中使用,请求用不到)
CookieHeader 设置 cookie
UserAgentHeader 设置 User-Agent

QVariant

QVariant 可以存储各种类型的数据,包括整数、字符串、日期等。

代码示例:设置请求头

cpp 复制代码
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QVariant>
#include <QUrl>

int main() {
    QNetworkAccessManager manager;
    QNetworkRequest request(QUrl("http://example.com"));
    // 设置Content-Type头
    request.setHeader(QNetworkRequest::ContentTypeHeader, "application/json");
    // 设置User-Agent头
    request.setHeader(QNetworkRequest::UserAgentHeader, "MyApp/1.0");
    // 发送请求
    QNetworkReply *reply = manager.get(request);
    // 这里可以连接信号与槽来处理响应
    // connect(reply, &QNetworkReply::finished, ...);
    return 0;
}

QNetworkReply

QNetworkReply 表示一个 HTTP 响应

API 说明
error() 返回值是NetworkError,获取出错状态
errorString() 返回值是 QString获取出错原因的文本
readAll() 读取 响应体body
header(QNetworkRequest::KnownHeaders header) 通过 header 获取对应的 value值

NetworkError 是一个枚举类,集合了在处理请求期间发现的所有可能的错误条件。

其中,常用枚举值如下:

  • QNetworkReply::NoError 表示没有错误发生
  • QNetworkReply::ConnectionRefusedError 表示连接被拒绝,通常意味着服务器无法响应连接请求
  • QNetworkReply::RemoteHostClosedError 表示远程主机关闭了连接
  • QNetworkReply::HostNotFoundError 表示无法找到主机。通常意味着DNS解析失败
  • QNetworkReply::TimeoutError 表示请求超时
  • QNetworkReply::SslHandshakeFailedError 表示SLL/TLS 握手失败,通常意味着SSL证书验证失败或其他SLL/TLS错误,使用https通信时可能发生

当客户端收到完整的响应数据后,会触发 QNetworkReply::finished 信号
可通过信号槽机制,及时高效的处理响应数据

代码示例

给服务器发送一个 GET 请求

  1. 编写 UI文件,创建界面,其中包含一个 QLineEditQPushButton,和一个 QPlainTextEdit。再使用布局管理器规范界面布局
  1. 编写 widget.h,声明按钮槽函数QNetworkAccessManager
cpp 复制代码
class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    //"发送"按钮的点击信号的槽函数
    void on_pushButton_clicked();

private:
    Ui::Widget *ui;
    QNetworkAccessManager *manager;
};
  1. 编写 widget.cpp,实例化并实现槽函数
cpp 复制代码
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //实例化
    manager = new QNetworkAccessManager(this);
}

void Widget::on_pushButton_clicked()
{
    //1. 获取输入栏url,构造URL
    const QString &text = ui->lineEdit->text();
    QUrl url(text);
    //2. 构造并发送请求
    QNetworkRequest request(url);
    QNetworkReply *responce = manager->get(request);
    //3. 连接信号槽,收到完整响应才读取数据
    connect(responce, &QNetworkReply::finished, this, [=](){
        if(responce->error() == QNetworkReply::NoError)
        {
            //数据没有问题
            QString html = responce->readAll();
            ui->plainTextEdit->setPlainText(html);
        }
        else//有问题
            QMessageBox::critical(this, "HTTP响应出错", responce->errorString());
    });
}

次数使用 QPlainTextEdit,将响应体中的html文本转化为纯文本,如果使用类似QTextEdit,会对html文本进行富文本解析,若得到的 html 代码复杂,会导致界面渲染缓慢甚至卡住

运行结果如下:

结束语

感谢你的阅读

如果觉得本篇文章对你有所帮助的话,不妨点个赞支持一下博主,拜托啦,这对我真的很重要。

相关推荐
weixin_307779135 分钟前
Linux下GCC和C++实现统计Clickhouse数据仓库指定表中各字段的空值、空字符串或零值比例
linux·运维·c++·数据仓库·clickhouse
FakeOccupational29 分钟前
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
网络·游戏
秦少游在淮海1 小时前
C++ - string 的使用 #auto #范围for #访问及遍历操作 #容量操作 #修改操作 #其他操作 #非成员函数
开发语言·c++·stl·string·范围for·auto·string 的使用
AAA废品回收站陈师傅1 小时前
68常用控件_QGroupBox的使用
qt
const5441 小时前
cpp自学 day2(—>运算符)
开发语言·c++
明月醉窗台1 小时前
qt使用笔记二:main.cpp详解
数据库·笔记·qt
虾球xz2 小时前
CppCon 2015 学习:CLANG/C2 for Windows
开发语言·c++·windows·学习
沉到海底去吧Go2 小时前
【图片自动识别改名】识别图片中的文字并批量改名的工具,根据文字对图片批量改名,基于QT和腾讯OCR识别的实现方案
数据库·qt·ocr·图片识别自动改名·图片区域识别改名·pdf识别改名
CodeWithMe2 小时前
【C/C++】namespace + macro混用场景
c语言·开发语言·c++
fei_sun2 小时前
【计算机网络】三报文握手建立TCP连接
网络·tcp/ip·计算机网络