版权声明:若无来源注明,Techie亮博客文章均为原创。 转载请以链接形式标明本文标题和地址:
本文标题:Qt使用QNetworkAccessManager实现Http操作     本文地址:https://www.techieliang.com/2017/12/649/

1. 介绍

QtNetwork是Qt网络操作模块,提供了基于TCP/IP的各种API,除了之前介绍过的最基础的TCP及UDP通讯:QTcpSocket-Qt使用Tcp通讯实现服务端和客户端QUdpSocket-Qt使用Udp通讯实现服务端和客户端,还提供了HTTP、HTTPS、FTP等高级API,并统一使用QNetworkAccessManager进行操作。Ftp使用请见:Qt使用QNetworkAccessManager实现Ftp操作

qt4x分别使用QFtp和QHttp,5以后统一用QNetworkAccessManager

HTTP请求方法

此节内容来源:HTTP请求方法

根据HTTP标准,HTTP请求可以使用多种请求方法。

HTTP1.0定义了三种请求方法: GET, POST 和 HEAD方法。

HTTP1.1新增了五种请求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 方法。

序号 方法 描述
1 GET 请求指定的页面信息,并返回实体主体。
2 HEAD 类似于get请求,只不过返回的响应中没有具体的内容,用于获取报头
3 POST 向指定资源提交数据进行处理请求(例如提交表单或者上传文件)。数据被包含在请求体中。POST请求可能会导致新的资源的建立和/或已有资源的修改。
4 PUT 从客户端向服务器传送的数据取代指定的文档的内容。
5 DELETE 请求服务器删除指定的页面。
6 CONNECT HTTP/1.1协议中预留给能够将连接改为管道方式的代理服务器。
7 OPTIONS 允许客户端查看服务器的性能。
8 TRACE 回显服务器收到的请求,主要用于测试或诊断。

2. QNetworkAccessManager接口介绍

官方文档:QNetworkAccessManager

接口很多,就不全部复制过来了,如果机器装着qt5,可以直接在助手看。

可以一目了然的看到几个熟悉词汇的api:post、get、put、head,当然还有几个cookie相关的方法。

  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)

可以发现使用manager还需要几个类:QNetworkRequest 专门用于请求的,QNetworkReply 接收请求的响应

2.1. QNetworkRequest

同样看帮助文档:http://doc.qt.io/qt-5/qnetworkrequest.html

  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)

主要就是这几个写方法,分别对一个请求的不同类进行配置。

客户端发送一个HTTP请求到服务器的请求消息包括以下格式:请求行(request line)、请求头部(header)、空行和请求数据四个部分组成,下图给出了请求报文的一般格式。请求行组成:请求方法+空格+url+空格+协议版本+回车符+换行符。详情见HTTP 消息结构

对于header,qt提供了一个枚举类型KnownHeaders分别表示不同项:

Constant Value Description
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.

请求类主要是进行对于地址,还给出了QUrl 类,详情见后。

2.2. QNetworkReply

帮助文档:http://doc.qt.io/qt-5/qnetworkreply.html

此类继承自QIODevice,可使用QIODevice的所有接口,包括readall读取接收的所有信息。

同时此类提供了finished信号,在响应完斥候发出此信号,可关联自定义槽函数函数,做响应处理。

提供了attribute属性函数,可以判断响应的类型,比如RedirectionTargetAttribute是目标url告知进行重定向

QNetworkReply不会自动释放空间,一定要主动处理内存释放,可以调用QObject::deleteLater令其自动释放空间

3. 范例

.h文件

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

.cpp文件

  1. #include "mainwindow.h"
  2. #include "ui_mainwindow.h"
  3. MainWindow::MainWindow(QWidget *parent) :
  4. QMainWindow(parent),
  5. ui(new Ui::MainWindow) {
  6. ui->setupUi(this);
  7. reply = Q_NULLPTR;
  8. }
  9. MainWindow::~MainWindow() {
  10. delete ui;
  11. }
  12. void MainWindow::Get(QUrl u) {
  13. QNetworkRequest request;
  14. url=u;
  15. request.setUrl(url);
  16. if(reply != Q_NULLPTR) {//更改reply指向位置钱一定要保证之前的定义了自动delete
  17. reply->deleteLater();
  18. }
  19. reply = manager.get(request);
  20. qDebug() << "start get";
  21. connect(reply, &QNetworkReply::finished, this, &MainWindow::finished);
  22. }
  23. void MainWindow::on_pushButton_clicked() {
  24. html_text = "";
  25. Get(QUrl("http://www.baidu.com/"));
  26. }
  27. void MainWindow::finished() {
  28. QByteArray bytes = reply->readAll();
  29. const QVariant redirectionTarget = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
  30. reply->deleteLater();
  31. reply = Q_NULLPTR;
  32. if (!redirectionTarget.isNull()) {//如果网址跳转重新请求
  33. const QUrl redirectedUrl = url.resolved(redirectionTarget.toUrl());
  34. qDebug()<<"redirectedUrl:"<<redirectedUrl.url();
  35. Get(redirectedUrl);
  36. return;
  37. }
  38. qDebug()<<"finished";
  39. html_text = bytes;
  40. qDebug()<<"get ready,read size:"<<html_text.size();
  41. // QFile f("result.html");//写出文件
  42. // f.open(QFile::WriteOnly);
  43. // f.write(bytes);
  44. // f.close();
  45. }

程序很简单 on_pushButton_clicked 作为范例的入口,当点击按钮时开始访问,会传递百度的网址的到Get函数。

get函数中进行get操作,并把返回值的reply connect到finished槽。

finished中首先判断响应头是否有重定向要求,如果有重定向则销毁当前reply并利用指定的新地址重新调用get,可以试验“www.sina.com”会指向”www.sina.com.cn”

最后通过readll读取所有数据并保存到文件,双击打开文件可以看到效果。当然不会包含图片信息

4. 其他

4.1. post使用

post其实和get类似,只不过同时还传递了串数据

post(request, data)即可,其他操作完全一样

4.2. QUrlQuery

http://techieliang.com/wp-admin/post.php?post=000&action=edit&name=techieliang

对于上述指令直接使用QUrl赋值也是可以的,但是如果后续参数一直在变动,需要自己封装一个字符串拼接的过程。简单的办法是使用QUrlQuery

  1. QUrl url("http://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("http://techieliang.com/wp-admin/post.php?");
  13. qDebug()<<url.url();
  14. url.setQuery(tt);
  15. qDebug()<<url.url();

结果

  1. "http://techieliang.com/wp-admin/post.php?post=000&action=edit&name=techieliang"
  2. "http://techieliang.com/wp-admin/post.php?post=000"
  3. "http://techieliang.com/wp-admin/post.php?"
  4. "http://techieliang.com/wp-admin/post.php?post=000"
  • setUrl会将Url改为新值,并清空Query,直接更改url后需要重新setQuery
  • setQuery不会改变Url值,可以不断的setQuery去构造不同的参数
  • QUrl会自动处理url后的?若setUrl的值末尾没有?会自动在url和query之间增加,若已经包含则不会重复
转载请以链接形式标明本文标题和地址:Techie亮博客 » Qt使用QNetworkAccessManager实现Http操作

Qt使用QNetworkAccessManager实现Http操作的更多相关文章

  1. Qt使用QNetworkAccessManager实现Ftp操作

    版权声明:若无来源注明,Techie亮博客文章均为原创. 转载请以链接形式标明本文标题和地址: 本文标题:Qt使用QNetworkAccessManager实现Ftp操作     本文地址:http: ...

  2. paip.c++ qt 目录遍历以及文件操作

    paip.c++ qt 目录遍历以及文件操作 作者Attilax ,  EMAIL:1466519819@qq.com  来源:attilax的专栏 地址:http://blog.csdn.net/a ...

  3. Qt中与文件目录相关操作

    一.与文件目录操作有关操作. Qt中与文件目录相关的操作在QDir中,需加入#include <QDir>语句. QDir::drives()是列出电脑根目录下的所有目录,返回的是QFil ...

  4. Qt:QNetworkAccessManager

    0.说明 QNetworkAccessManager允许应用发送Request并接受回应. 网络访问API是围绕一个QNetworkAccessManager对象构建的,该对象保留了所有它发送的请求的 ...

  5. Qt之课外实践——文件操作(简单清道夫)

    说明:这个小项目是关于文件操作的.主要的功能有:重复文件的查找(根据文件的大小),说白了,就是讲大小相同的文件在一起显示出来,供用户自由的选择删除.这个360云盘里的文件去重还差的很远.还有空文件夹的 ...

  6. Qt使用Cookies对网站操作之Get和POST

    1.添加QNetwork模块: a.Qt Creator中打开.pro文件添加QT+=Network; b.VS_Qt中项目属性中Qt Project Settings中Qmodules中勾选”QNe ...

  7. QT 一些非常常用的操作

    一   如果在窗体关闭前自行判断是否可关闭二   如何用打开和保存文件对话框  三   如何使用警告.信息等对话框  四   在Windows下Qt里为什么没有终端输出五   想在源代码中直接使用中文 ...

  8. 4.关于QT中的QFile文件操作,QBuffer,Label上添加QPixmap,QByteArray和QString之间的区别,QTextStream和QDataStream的区别,QT内存映射(

     新建项目13IO 13IO.pro HEADERS += \ MyWidget.h SOURCES += \ MyWidget.cpp QT += gui widgets network CON ...

  9. QT文件(夹)操作---QFile、QDir、QFileInfo、QTextStream和QDataStream异同

    1.1    文件和目录 QFile.QBuffer和QTcpSocket可支持读写设备,用open函数打开,用write或putChar函数写入.用read和readLine或readAll进行读取 ...

随机推荐

  1. STM32(2)——GPIO

    对于初学者而言,最简单的是对芯片上的IO进行操作,我们学习ARM时候,第一个工程就是点亮LED,STM32F103ZET6通用输入输出接口(General-Purpose Inputs/Outputs ...

  2. git提交代码速度过慢解决方法(macos)

    iterm2中ping下github.com和github.global.ssl.fastly.net $ ping github.com 得到以下 PING github.com (192.30.2 ...

  3. android studio 调试技巧(简直太好用)

    android studio 调试技巧(简直太好用) 说到android studio的调试,很多人可能会说,这有什么可讲的不就是一个断点调试么,刚开始我也是这么认为的,直到我了解之后,才发现,调试原 ...

  4. python的subprocess基本

    先在同一个文件夹下创建两个.py文件. 第一个:13.py # -*- coding: utf-8 -*- __author__ = "YuDian" ''' multiproce ...

  5. go VS NET 字符串操作能力

    今天拿golang 与 NET4.0 做了在字符串方面的性能比较,看看谁牛! 一.读取txt文本文件 GO的代码: readbuf, _ := ioutil.ReadFile(userFile) st ...

  6. sort与qsort的异同

    主要内容: 1.qsort的用法 2.sort的用法 3.qsort和sort的区别 qsort的用法: 原 型: void qsort(void *base, int nelem, int widt ...

  7. 电脑开机svchost.exe报错

    一.问题: 这几天电脑开机一直弹出一个对话框说:svchost.exe文件不能运行,百度后发现是用于动态运行库的依赖(dll),不过不知道是个啥东西 二.解决: 开机弹框虽然不影响电脑的使用,但是看着 ...

  8. 【MongoDB】如何注册windows服务

    一.为什么要注册windows服务 mongodb启动比较麻烦,每次都要cmd去开启.注册windows服务,可以设置开机启动,比较友好. 二.如何注册windows服务 1.安装mongodb 2. ...

  9. Qt开发者关于QThread的咆哮——你们都用错了

    Qt开发者关于QThread的咆哮——你们都用错了 我们(Qt用户)正广泛地使用IRC来进行交流.我在Freenode网站挂出了#qt标签,用于帮助大家解答问题.我经常看到的一个问题(这让我不厌其烦) ...

  10. 我们一起学习WCF 第七篇会话模式

    会话:就是客户端和服务端之间的谈话.比喻A和B去登陆网站,那么A用户登陆进去肯定显示A的用户详情,那么这就是A和服务器之间的交流.同样B用户登陆之后显示B的详情,这就表示这是B和服务器之间的交流. 如 ...