核心API
HTTP本质是基于TCP实现的,Qt只提供了HTTP的客户端,没有提供HTTP服务器的库,也就是说这个客户端的库,是基于TCP socket封装的。
QNetworkAccessManager
提供了HTTP的核心操作。
方法 | 说明 |
---|---|
get(const QNetworkRequest&) | 发起一个HTTP GET请求,返回QNetworkReply对象 |
post(const QNetworkRequest&, const QByteArray&) | 发起一个HTTP POST请求,返回QNetworkReply对象 |
QNetworkRequest
表示一个HTTP请求(不含body)
如果需要发送一个带有body的请求,会在
QNetworkAccessManager
的post方法中通过单独的参数来传入body
方法 | 说明 |
---|---|
QNetworkRequest(const QUrl&) | 通过URL构造一个HTTP请求 |
setHeader(QNetworkRequest::KnowHeaders header, const QVariant &value) | 设置请求头 |
这个
QVariant
就有点类似于C语言里面的void*
QNetworkRequest::KnowHeaders
是枚举类型,常用取值
取值 | 说明 |
---|---|
ContentTypeHeader | 描述body的类型 |
ContentLengthHeader | 描述body的长度 |
LocationHeader | 用于重定向报文中指定重定向地址 |
CookieHeader | 设置cookie |
UserAgentHeader | 设置User-Agent |
QNetworkReply
表示HTTP响应,这个类也是QIODevice
的子类
方法 | 说明 |
---|---|
error() | 获取出错状态 |
errorString() | 获取出错原因的文本 |
readAll() | 读取响应body |
header(QNetworkRequest::KnowHeaders header) | 读取响应指定的header的值 |
QNetworkReply
还有一个重要的信号finished
会在客户端收到完整的响应数据之后触发
HTTP客户端
Tips:
这里响应的结果,大概率是一个HTML;
使用
QPlainTextEdit
,能够看到最原始的模样;如果使用
QTextEdit
,它会对HTML进行解析,最终得到的效果,就不是最原始的HTML,如果HTML比较大,可能还会造成卡顿。
get
不是阻塞函数,只管发送,不管接收,QNetworkReply
里面有一个finished
信号,当响应返回之后,这个信号触发了
widget.h
:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
QNetworkAccessManager *manager;
};
#endif // WIDGET_H
widget.cpp
:
#include "widget.h"
#include "ui_widget.h"
#include <QNetworkReply>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
this->setWindowTitle("http客户端");
manager = new QNetworkAccessManager(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_pushButton_clicked()
{
//输入框获取url
QUrl url(ui->lineEdit->text());
//构造http请求
QNetworkRequest request(url);
//发送请求
QNetworkReply *response = manager->get(request);
//信号槽处理响应
connect(response, &QNetworkReply::finished, this, [=](){
if(response->error() == QNetworkReply::NoError)
{
QString html = response->readAll();
ui->plainTextEdit->setPlainText(html);
}
else
{
ui->plainTextEdit->setPlainText(response->errorString());
}
//释放response
response->deleteLater();
});
}
在事件中,HTTP CIient获取的数据,不一定是html,更大可能是双方互相约定好的数据交互格式。