Qt using QNetworkAccessManager to implement Http operations

introduce

QtNetwork is a Qt network operation module, which provides various API s based on TCP/IP.

qt4x Use separately QFtp and QHttp,5 It will be used uniformly in the future QNetworkAccessManager

HTTP request method

According to the HTTP standard, HTTP requests can use a variety of request methods.

HTTP1.0 defines three request methods: GET, POST and HEAD.

HTTP1.1. Five request methods are added: OPTIONS, PUT, DELETE, TRACE and CONNECT methods.

Serial numbermethoddescribe
1 GET Request the specified page information and return the entity body.
2 HEAD It is similar to the get request, except that there is no specific content in the returned response to get the header
3 POST Submit data to the specified resource for processing requests (such as submitting forms or uploading files). The data is contained in the request body. POST requests may lead to the establishment of new resources and / or the modification of existing resources.
4 PUT The data transmitted from the client to the server replaces the contents of the specified document.
5 DELETE Requests the server to delete the specified page.
6 CONNECT HTTP/1.1 protocol is reserved for proxy servers that can change the connection to pipeline mode.
7 OPTIONS Allows clients to view the performance of the server.
8 TRACE Echo the request received by the server, which is mainly used for testing or diagnosis.

Introduction to QNetworkAccessManager interface

There are many interfaces, so they are not all copied. If the machine is equipped with qt5, you can directly see it in the assistant.

You can clearly see several familiar vocabulary APIs: post, get, put, head, and, of course, several cookie related methods.

 1 QNetworkReply *get(const QNetworkRequest &request)
 2 QNetworkReply *head(const QNetworkRequest &request)
 3 bool isStrictTransportSecurityEnabled() const
 4 bool isStrictTransportSecurityStoreEnabled() const
 5 NetworkAccessibility networkAccessible() const
 6 QNetworkReply *post(const QNetworkRequest &request, QIODevice *data)
 7 QNetworkReply *post(const QNetworkRequest &request, const QByteArray &data)
 8 QNetworkReply *post(const QNetworkRequest &request, QHttpMultiPart *multiPart)
 9 QNetworkProxy proxy() const
10 QNetworkProxyFactory *proxyFactory() const
11 QNetworkReply *put(const QNetworkRequest &request, QIODevice *data)
12 QNetworkReply *put(const QNetworkRequest &request, const QByteArray &data)
13 QNetworkReply *put(const QNetworkRequest &request, QHttpMultiPart *multiPart)

It can be found that several classes are needed to use manager: QNetworkRequest is specifically used for requests, and QNetworkReply receives the response of requests

QNetworkRequest

1 void setAttribute(Attribute code, const QVariant &value)
2 void setHeader(KnownHeaders header, const QVariant &value)
3 void setMaximumRedirectsAllowed(int maxRedirectsAllowed)
4 void setOriginatingObject(QObject *object)
5 void setPriority(Priority priority)
6 void setRawHeader(const QByteArray &headerName, const QByteArray &headerValue)
7 void setSslConfiguration(const QSslConfiguration &config)
8 void setUrl(const QUrl &url)

These write methods are mainly used to configure different classes of a request.

The request message that the client sends an HTTP request to the server includes the following formats: request line, request header, blank line and request data. The following figure shows the general format of the request message. Request line composition: request method + space + url + space + protocol version + carriage return + line feed.

For headers, qt provides an enumeration type. KnownHeaders represent different items:

ConstantValueDescription
QNetworkRequest::ContentDispositionHeader 6 Corresponds to the HTTP Content-Disposition header and contains a string containing the disposition type (for instance, attachment) and a parameter (for instance, filename).
QNetworkRequest::ContentTypeHeader 0 Corresponds to the HTTP Content-Type header and contains a string containing the media (MIME) type and any auxiliary data (for instance, charset).
QNetworkRequest::ContentLengthHeader 1 Corresponds to the HTTP Content-Length header and contains the length in bytes of the data transmitted.
QNetworkRequest::LocationHeader 2 Corresponds to the HTTP Location header and contains a URL representing the actual location of the data, including the destination URL in case of redirections.
QNetworkRequest::LastModifiedHeader 3 Corresponds to the HTTP Last-Modified header and contains a QDateTime representing the last modification date of the contents.
QNetworkRequest::CookieHeader 4 Corresponds to the HTTP Cookie header and contains a QList<QNetworkCookie> representing the cookies to be sent back to the server.
QNetworkRequest::SetCookieHeader 5 Corresponds to the HTTP Set-Cookie header and contains a QList<QNetworkCookie> representing the cookies sent by the server to be stored locally.
QNetworkRequest::UserAgentHeader 7 The User-Agent header sent by HTTP clients.
QNetworkRequest::ServerHeader 8 The Server header received by HTTP clients.

The request class is mainly for addresses, and the QUrl class is also given. See below for details.

QNetworkReply

This class inherits from QIODevice and can use all interfaces of QIODevice, including readall, to read all received information.

At the same time, this class provides a finished signal. After responding to the scouts, this signal can be associated with a user-defined slot function for response processing.

The attribute attribute function is provided to determine the type of response. For example, redirection targetattribute is the target url to tell redirection

QNetworkReply will not automatically free space. You must actively handle memory release. You can call QObject::deleteLater to make it automatically free space

example

. h file

 1 #ifndef MAINWINDOW_H
 2 #define MAINWINDOW_H
 3 
 4 #include <QMainWindow>
 5 #include <QtNetwork>
 6 #include <QFile>
 7 namespace Ui {
 8 class MainWindow;
 9 }
10 
11 class MainWindow : public QMainWindow {
12     Q_OBJECT
13 
14 public:
15     explicit MainWindow(QWidget *parent = 0);
16     ~MainWindow();
17     void Get(QUrl u);
18 private slots:
19     void on_pushButton_clicked();
20     void finished();
21 private:
22     Ui::MainWindow *ui;
23     QNetworkAccessManager manager;
24     QUrl url;
25     QNetworkReply *reply;
26     QString html_text;
27 };
28 
29 #endif // MAINWINDOW_H

. cpp file

 1 #include "mainwindow.h"
 2 #include "ui_mainwindow.h"
 3 
 4 MainWindow::MainWindow(QWidget *parent) :
 5     QMainWindow(parent),
 6     ui(new Ui::MainWindow) {
 7     ui->setupUi(this);
 8     reply = Q_NULLPTR;
 9 }
10 
11 MainWindow::~MainWindow() {
12     delete ui;
13 }
14 
15 void MainWindow::Get(QUrl u) {
16     QNetworkRequest request;
17     url=u;
18     request.setUrl(url);
19     if(reply != Q_NULLPTR) {//change reply To point to the location, be sure to ensure that the previous definition is automatic delete
20         reply->deleteLater();
21     }
22     reply = manager.get(request);
23     qDebug() << "start get";
24     connect(reply, &QNetworkReply::finished, this, &MainWindow::finished);
25 }
26 
27 void MainWindow::on_pushButton_clicked() {
28     html_text = "";
29     Get(QUrl("https://www.baidu.com/"));
30 
31 }
32 
33 void MainWindow::finished() {
34     QByteArray bytes = reply->readAll();
35     const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
36     reply->deleteLater();
37     reply = Q_NULLPTR;
38     if (!redirectionTarget.isNull()) {//If the URL jumps, re request
39         const QUrl redirectedUrl = url.resolved(redirectionTarget.toUrl());
40         qDebug()<<"redirectedUrl:"<<redirectedUrl.url();
41         Get(redirectedUrl);
42         return;
43     }
44     qDebug()<<"finished";
45     html_text = bytes;
46     qDebug()<<"get ready,read size:"<<html_text.size();
47 //    QFile f("result.html");//Write file
48 //    f.open(QFile::WriteOnly);
49 //    f.write(bytes);
50 //    f.close();
51 }

The program is simple_ pushButton_ Clicked is the entry of the example. When you click the button to start accessing, it will pass Baidu's website to the Get function.

The get function performs the get operation and connects the reply of the return value to the finished slot.

In finished, first judge whether the response header has redirection requirements. If there is redirection, destroy the current reply and call get again with the specified new address. You can test that "www.sina.com" will point to "www.sina.com" com. cn”

Finally, read all data through readll and save it to a file. Double click to open the file to see the effect. Of course, it will not contain picture information

other

post usage

post is actually similar to get, except that it also passes a string of data

Just post(request, data). Other operations are exactly the same

QUrlQuery

For the above instructions, it is also possible to directly use QUrl assignment, but if the subsequent parameters are changing all the time, you need to encapsulate a string splicing process yourself. The easy way is to use QUrlQuery

 1 QUrl url("https://techieliang.com/wp-admin/post.php");
 2 QUrlQuery tt;
 3 tt.addQueryItem("post","000");
 4 tt.addQueryItem("action","edit");
 5 tt.addQueryItem("name","techieliang");
 6 url.setQuery(tt);
 7 qDebug()<<url.url();
 8 tt.clear();
 9 tt.addQueryItem("post","000");
10 url.setQuery(tt);
11 qDebug()<<url.url();
12 url.setUrl("https://techieliang.com/wp-admin/post.php?");
13 qDebug()<<url.url();
14 url.setQuery(tt);
15 qDebug()<<url.url();

result

1 "https://techieliang.com/wp-admin/post.php?post=000&action=edit&name=techieliang"
2 "https://techieliang.com/wp-admin/post.php?post=000"
3 "https://techieliang.com/wp-admin/post.php?"
4 "https://techieliang.com/wp-admin/post.php?post=000"
  • setUrl will change the URL to a new value and clear the Query. After changing the URL directly, you need to reset setQuery
  • setQuery does not change the Url value. You can constantly use setQuery to construct different parameters
  • QUrl will automatically process the information after the url? If there is no at the end of setUrl value? It will be automatically added between url and query. If it is already included, it will not be repeated

Keywords: Qt

Added by dagon on Wed, 12 Jan 2022 05:17:08 +0200