QHttp编程的一些笔记
2017-02-07 20:30
246 查看
遇到两个个博客的发送都是使用cookie来标识用户的:my.opera.com以及myspace.
请求头
请求头类:QHttpRequestHeader
设置请求方式(get/post)
QHttpRequestHeader::setRequest ("POST", "请求地址"); //post
QHttpRequestHeader::setRequest ("GET", "请求地址"); //get
请求地址可以不包含Host名称
设置请求头:
void QHttpRequestHeader::setValue(const QString & key, const QString & value)//各个变量设置
void QHttpRequestHeader::setValues ( const QList<QPair<QString, QString> > & values )//批量设置
编码
发送的内容编码有两种
multipart/form-data
application/x-www-form-urlencoded
application/x-www-form-urlencoded
使用的是URL编码,在QT中使用以下code来完成转换:
QByteArray afterData = QUrl::toPercentEncoding (befData, "&=");
befData是未转换之前的数据,函数返回的是转换后的QByteArray类型的编码。
除了大小写字母以外的所有符号都使用%n的方式表示(n为字符的两位编码)
使用QHttpRequestHeader::setValue ("content-type", "application/x-www-form-urlencoded");设置请求头
multipart/form-data
使用类似以下格式的代码进行传输:
--BlogDiary2007
Content-Disposition: form-data; name="表单控件名称"
数据
--BlogDiary2007
Content-Disposition: form-data; name="表单控件名称"
数据
--BlogDiary2007--
BlogDiary2007是各数据间的分割符,每一部分前面加上两个"--",整个表单数据完成后面再加"--"表示完成。
BlogDiary2007并不是特定的,但必须与你的请求头变量的相一致。
QHttpRequestHeader::setValue ("content-type", "multipart/form-data; boundary=BlogDiary2007");
一些用过的请求头变量
变量 值
COOKIE: COOKIE数据
HOST(此变量是必须的): 网站的HOST地址
USER_AGENT: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
不知道为何,USER_AGENT在myspace登陆时是必须的,弄得头崩额劽加上这个才弄好。只是标志客户端的版本而已呀,难道登陆myspace需要知道我用什么浏览器吗?不知道我改成BlogDiary会怎么样。
应答头
应答头类:QHttpResponseHeader
返回的值通过QHttpResponseHeader::value ("变量");获得
应答头的cookie的值为"set-cookie:cookie值",意为请求客户端设置,我登陆博客就是通过这个取得登陆身份的。
QHttp
声明:QHttp http = new QHttp ("远端服务器的Host名称");
向服务器请求数据:intQHttp::request (请求头,发送数据);//返回请求ID
返回当前的ID(接收到数据后):int QHttp::currentID ();
QHttp的请求方式类似于打印机的打印机队列一样,可以同时发送多个请求,但真正发送是按队列先后的方式发送请求。在接收到应答头后从当前ID(QHttp::currentID())知道是哪个请求返回的数据。
获得数据的长度(接收到数据后):int QHttp::bytesAvailable ();
应该与应答头的Content-Length的值一样,没验证过,但要注意的是此值可能并不是返回数据的整个大小,因为服务器可能不是一次能够发送完所有数据。
读取数据:read (读取数据缓冲, 上面bytesAvailable ()返回的大小);
获取错误:QHttp::Error QHttp::error ()
信号
请求数据后,当有数据进来后将会发送若干个信号提示服务器返回结果,使用对应Slot函数进行处理。
responseHeaderReceived (const QHttpResponseHeader& resp): 应答头已返回,可从返回的头获取应答信息
requestFinished(int id, bool error): 请求完成,error==true说明有错误发生,QHttp::error ()返回错误代码
readyRead (const QHttpResponseHeader& resp): 已有数据可读,如果数据很多,可能会发送多次信号
*****************************************************************************************
QHttp是Qt所提供有关网路的高阶API,可以协助您进行HTTP协定的进行,QHttp发出请求时是非同步的,请求的过程中会发出相关的Signal,您可以用Slot来接收这些Signal,并进行相关的处理。
以下先示範一個最基本的QHttp使用,程式將設計一個HttpGet類別: 以下先示范一个最基本的QHttp使用,程式将设计一个HttpGet类别:
HttpGet.h HttpGet.h
这个HttpGet可以让您指定档案的URL位址,以HTTP方式取得档案并储存在本地端,URL在Qt中以QUrl代表,当档案下载完成时,会发出finished()的Signal,当QHttp所排定的全部请求完成时,会发出done()的Signal,HttpGet类别中自定的Slot,就是用来接收QHttp的done() Signal以进行相关处理,这可以在HttpGet的实作看到:
HttpGet.cpp HttpGet.cpp
要使用Qt的网路相关类别,必须引进QtNetwork,并且必须在..pro档案中,加入以下这行以在建构过程中使用Qt网路模组:
QT += network
当呼叫HttpGet类别的downloadFile()方法时,程式中使用QUrl的path()来取得路径讯息,如果路径讯息中没有包括档名,就使用预设的"index.html"作为请求的对象及下载后存档时的档名,要使用QHttp来请求档案时,必须使用setHost ()来设定主机及连接埠资讯,接着使用get()方法发出请求,并告知下载的档案要到用哪个QFile来存档。
当QHttp所有请求处理完毕后,会发出done()的Signal,程式中将之连接至HttpGet的done()来处理,处理完成之后,再发出finished()的Signal。
以下写个简单的程式来测试HttpGet:
main.cpp main.cpp
程式中将HttpGet的finished()的Signal连接至QCoreApplication的quit(),如此当下载档案完成后,可以直接关闭应用程式。
Qt的QHttp与QFtp在使用上有许多类似的地方,可以在以上的范例看到一些特性,以下再整理出相关特性:
非阻斷行為,請求是非同步的。 非阻断行为,请求是非同步的。
您可以排定一連串的請求,每個請求都有一個Command ID,QHttp的requestStarted()與requestFinished()等Signal會帶有請求的Command ID,您可以用以追蹤請求的執行。 您可以排定一连串的请求,每个请求都有一个Command ID,QHttp的requestStarted()与requestFinished()等Signal会带有请求的Command ID,您可以用以追踪请求的执行。
在資料傳輸的過程中,有相關的Signal可以追蹤進度,像是QHttp的dataReadProgress()、dataSendProgress()等Signal。 在资料传输的过程中,有相关的Signal可以追踪进度,像是QHttp的dataReadProgress()、dataSendProgress()等Signal。
支援QIODevice的寫入(下載)與讀取(上傳),還有以QByteArray為基礎的API。 支援QIODevice的写入(下载)与读取(上传),还有以QByteArray为基础的API。
QHttp还可以针对请求标头、HTTPS等加以处理,在Qt的线上文件中,有个QHttp的范例Http Example ,对QHttp的使用有更完整的示范。
******************************************************************************************
在Qt中使用QHttp下载带有?问号查询的Url地址内容(含源码 )
本站所有文章由本站和原作者保留一切权力,仅在保留本版权信息、原文链接、原文作者的情况下允许转载,转载请勿删改原文内容, 并不得用于商业用途。 谢谢合作。
原文链接:在Qt中使用QHttp下载带有?问号查询的Url地址内容(含源码 )
在<<C++ GUI Programming With Qt4>>这本书的第十四章介绍了用QHttp::get()函数去下载一个网页数据。但是这个例子只能处理常规的下载,也就是实现http请求中的“GET”请求,而不能实现”POST”请求。举例来说就是,QHttp::get()
能够下载 http://www.google.com/index.html 而不能下载 http://www.cuteqt.com/blog/?feed=rss 因为后者需要的下载方式不一样,可以用另外一个函数QHttp::request()来实现。
假如我们要执行上面第二个地址的请求,写出来的代码应该是下面的样子。
34 http.setHost("www.cuteqt.com/blog");
35 rssfile.setFileName("./feed.list");
36 rssfile.open(QIODevice::WriteOnly | QIODevice::Truncate);
37 QByteArray inputStr("feed=rss");
38 QHttpRequestHeader header("POST", "/blog/");
39 header.setValue("Content-Type", "application/x-www-form-urlencoded");
40 header.setValue("Host", "www.cuteqt.com/blog");
41 requestid=http.request(header,inputStr,&rssfile);
42 http.close();
34:http是QHttp 类型的,设置好要访问的主机
35:rssfile是QFile类型,下载的网页会存放到这个文件里
37:这个inputStr就是我们查询的串,格式可以是key1=var1&key2=var2&key3=var3的格式
38:设置好主机下的请求路径
40:header里的Host值,还是这个主机名
41:前面配置好的参数,正式发出请求,第三个参数类型是QIODevice *,如果不想存到文件里,你也可以用QBuffer。返回值requestid的作用下面会提到。
http.close();
需要注意的是,QHttp中不管是get()还是request()都是异步请求,也就是命令发出后,随即返回。在数据处理完毕的时候会有SIGNAL信号发出。request()处理完毕的信号名叫SIGNAL(requestFinished(int id,bool)),第一个参数id正是和前面request返回的requestid,以此知道是哪一个http请求处理后的返回消息。用以下函数关联信号和槽
connect(&http, SIGNAL(requestFinished(int,bool)), this, SLOT(httpReqDone(int,bool)));
通用代码如下:
QList<QPair<QByteArray, QByteArray> > querylist;
querylist=url.encodedQueryItems();
if(querylist.size()!=0)
{
QByteArray querydata;
querydata.append(querylist[0].first);
querydata.append('=');
querydata.append(querylist[0].second);
for (int i = 1; i < querylist.size(); ++i) {
querydata.append('&');
querydata.append(querylist[i].first);
querydata.append('=');
querydata.append(querylist[i].second);
}
QHttpRequestHeader header("POST", url.path());
header.setValue("Content-Type", "application/x-www-form-urlencoded");
header.setValue("Host", url.host());
http.setHost(url.host());
http_request_id=http.request(header,querydata,&file);
qDebug()<<querydata;
http.close();
}
else
{
http.setHost(url.host(), url.port(80));
http.get(url.path(), &file);
http_request_id=0;
http.close();
}
http://blog.csdn.net/mociml/article/details/5622126
请求头
请求头类:QHttpRequestHeader
设置请求方式(get/post)
QHttpRequestHeader::setRequest ("POST", "请求地址"); //post
QHttpRequestHeader::setRequest ("GET", "请求地址"); //get
请求地址可以不包含Host名称
设置请求头:
void QHttpRequestHeader::setValue(const QString & key, const QString & value)//各个变量设置
void QHttpRequestHeader::setValues ( const QList<QPair<QString, QString> > & values )//批量设置
编码
发送的内容编码有两种
multipart/form-data
application/x-www-form-urlencoded
application/x-www-form-urlencoded
使用的是URL编码,在QT中使用以下code来完成转换:
QByteArray afterData = QUrl::toPercentEncoding (befData, "&=");
befData是未转换之前的数据,函数返回的是转换后的QByteArray类型的编码。
除了大小写字母以外的所有符号都使用%n的方式表示(n为字符的两位编码)
使用QHttpRequestHeader::setValue ("content-type", "application/x-www-form-urlencoded");设置请求头
multipart/form-data
使用类似以下格式的代码进行传输:
--BlogDiary2007
Content-Disposition: form-data; name="表单控件名称"
数据
--BlogDiary2007
Content-Disposition: form-data; name="表单控件名称"
数据
--BlogDiary2007--
BlogDiary2007是各数据间的分割符,每一部分前面加上两个"--",整个表单数据完成后面再加"--"表示完成。
BlogDiary2007并不是特定的,但必须与你的请求头变量的相一致。
QHttpRequestHeader::setValue ("content-type", "multipart/form-data; boundary=BlogDiary2007");
一些用过的请求头变量
变量 值
COOKIE: COOKIE数据
HOST(此变量是必须的): 网站的HOST地址
USER_AGENT: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 2.0.50727)
不知道为何,USER_AGENT在myspace登陆时是必须的,弄得头崩额劽加上这个才弄好。只是标志客户端的版本而已呀,难道登陆myspace需要知道我用什么浏览器吗?不知道我改成BlogDiary会怎么样。
应答头
应答头类:QHttpResponseHeader
返回的值通过QHttpResponseHeader::value ("变量");获得
应答头的cookie的值为"set-cookie:cookie值",意为请求客户端设置,我登陆博客就是通过这个取得登陆身份的。
QHttp
声明:QHttp http = new QHttp ("远端服务器的Host名称");
向服务器请求数据:intQHttp::request (请求头,发送数据);//返回请求ID
返回当前的ID(接收到数据后):int QHttp::currentID ();
QHttp的请求方式类似于打印机的打印机队列一样,可以同时发送多个请求,但真正发送是按队列先后的方式发送请求。在接收到应答头后从当前ID(QHttp::currentID())知道是哪个请求返回的数据。
获得数据的长度(接收到数据后):int QHttp::bytesAvailable ();
应该与应答头的Content-Length的值一样,没验证过,但要注意的是此值可能并不是返回数据的整个大小,因为服务器可能不是一次能够发送完所有数据。
读取数据:read (读取数据缓冲, 上面bytesAvailable ()返回的大小);
获取错误:QHttp::Error QHttp::error ()
信号
请求数据后,当有数据进来后将会发送若干个信号提示服务器返回结果,使用对应Slot函数进行处理。
responseHeaderReceived (const QHttpResponseHeader& resp): 应答头已返回,可从返回的头获取应答信息
requestFinished(int id, bool error): 请求完成,error==true说明有错误发生,QHttp::error ()返回错误代码
readyRead (const QHttpResponseHeader& resp): 已有数据可读,如果数据很多,可能会发送多次信号
*****************************************************************************************
QHttp是Qt所提供有关网路的高阶API,可以协助您进行HTTP协定的进行,QHttp发出请求时是非同步的,请求的过程中会发出相关的Signal,您可以用Slot来接收这些Signal,并进行相关的处理。
以下先示範一個最基本的QHttp使用,程式將設計一個HttpGet類別: 以下先示范一个最基本的QHttp使用,程式将设计一个HttpGet类别:
HttpGet.h HttpGet.h
#ifndef HTTPGET_H #ifndef HTTPGET_H #define HTTPGET_H #define HTTPGET_H #include <QObject> #include <QObject> class QUrl; class QUrl; class QHttp; class QHttp; class QFile; class QFile; class HttpGet : public QObject { class HttpGet : public QObject { Q_OBJECT Q_OBJECT public: public: HttpGet(QObject *parent = 0); HttpGet(QObject *parent = 0); void downloadFile(const QUrl &url); void downloadFile(const QUrl &url); signals: signals: void finished(); void finished(); private slots: private slots: void done(bool error); void done(bool error); private: private: QHttp *http; QHttp *http; QFile *file; QFile *file; }; }; #endif #endif
这个HttpGet可以让您指定档案的URL位址,以HTTP方式取得档案并储存在本地端,URL在Qt中以QUrl代表,当档案下载完成时,会发出finished()的Signal,当QHttp所排定的全部请求完成时,会发出done()的Signal,HttpGet类别中自定的Slot,就是用来接收QHttp的done() Signal以进行相关处理,这可以在HttpGet的实作看到:
HttpGet.cpp HttpGet.cpp
#include <QtNetwork> #include <QtNetwork> #include <QFile> #include <QFile> #include <iostream> #include <iostream> #include "HttpGet.h" #include "HttpGet.h" using namespace std; using namespace std; HttpGet::HttpGet(QObject *parent) : QObject(parent) { HttpGet::HttpGet(QObject *parent) : QObject(parent) { http = new QHttp(this); http = new QHttp(this); connect(http, SIGNAL(done(bool)), this, SLOT(done(bool))); connect(http, SIGNAL(done(bool)), this, SLOT(done(bool))); }} void HttpGet::downloadFile(const QUrl &url) { void HttpGet::downloadFile(const QUrl &url) { QFileInfo fileInfo(url.path()); QFileInfo fileInfo(url.path()); QString fileName = fileInfo.fileName(); QString fileName = fileInfo.fileName(); if (fileName.isEmpty()) { if (fileName.isEmpty()) { fileName = "index.html"; fileName = "index.html"; } } file = new QFile(fileName); file = new QFile(fileName); if (!file->open(QIODevice::WriteOnly)) { if (!file->open(QIODevice::WriteOnly)) { cerr << "Unable to save the file" << endl; cerr << "Unable to save the file" << endl; delete file; delete file; file = 0; file = 0; return; return; } } http->setHost(url.host(), url.port(80)); http->setHost(url.host(), url.port(80)); http->get(url.path(), file); http->get(url.path(), file); http->close(); http->close(); } } void HttpGet::done(bool error) { void HttpGet::done(bool error) { if (error) { if (error) { cerr << "Error: " << qPrintable(http->errorString()) << endl; cerr << "Error: " << qPrintable(http->errorString()) << endl; } else { } else { cerr << "File downloaded as " << qPrintable(file->fileName()) cerr << "File downloaded as " << qPrintable(file->fileName()) << endl; << endl; } } file->close(); file->close(); delete file; delete file; file = 0; file = 0; emit finished(); emit finished(); } }
要使用Qt的网路相关类别,必须引进QtNetwork,并且必须在..pro档案中,加入以下这行以在建构过程中使用Qt网路模组:
QT += network
当呼叫HttpGet类别的downloadFile()方法时,程式中使用QUrl的path()来取得路径讯息,如果路径讯息中没有包括档名,就使用预设的"index.html"作为请求的对象及下载后存档时的档名,要使用QHttp来请求档案时,必须使用setHost ()来设定主机及连接埠资讯,接着使用get()方法发出请求,并告知下载的档案要到用哪个QFile来存档。
当QHttp所有请求处理完毕后,会发出done()的Signal,程式中将之连接至HttpGet的done()来处理,处理完成之后,再发出finished()的Signal。
以下写个简单的程式来测试HttpGet:
main.cpp main.cpp
#include <QCoreApplication> #include <QCoreApplication> #include <QUrl> #include <QUrl> #include "HttpGet.h" #include "HttpGet.h" #include <iostream> #include <iostream> using namespace std; using namespace std; int main(int argc, char *argv[]) { int main(int argc, char *argv[]) { QCoreApplication app(argc, argv); QCoreApplication app(argc, argv); HttpGet getter; HttpGet getter; getter.downloadFile(QUrl("http://caterpillar.onlyfun.net/index.html")); getter.downloadFile(QUrl("http://caterpillar.onlyfun.net/index.html")); QObject::connect(&getter, SIGNAL(finished()), &app, SLOT(quit())); QObject::connect(&getter, SIGNAL(finished()), &app, SLOT(quit())); return app.exec(); return app.exec(); } }
程式中将HttpGet的finished()的Signal连接至QCoreApplication的quit(),如此当下载档案完成后,可以直接关闭应用程式。
Qt的QHttp与QFtp在使用上有许多类似的地方,可以在以上的范例看到一些特性,以下再整理出相关特性:
非阻斷行為,請求是非同步的。 非阻断行为,请求是非同步的。
您可以排定一連串的請求,每個請求都有一個Command ID,QHttp的requestStarted()與requestFinished()等Signal會帶有請求的Command ID,您可以用以追蹤請求的執行。 您可以排定一连串的请求,每个请求都有一个Command ID,QHttp的requestStarted()与requestFinished()等Signal会带有请求的Command ID,您可以用以追踪请求的执行。
在資料傳輸的過程中,有相關的Signal可以追蹤進度,像是QHttp的dataReadProgress()、dataSendProgress()等Signal。 在资料传输的过程中,有相关的Signal可以追踪进度,像是QHttp的dataReadProgress()、dataSendProgress()等Signal。
支援QIODevice的寫入(下載)與讀取(上傳),還有以QByteArray為基礎的API。 支援QIODevice的写入(下载)与读取(上传),还有以QByteArray为基础的API。
QHttp还可以针对请求标头、HTTPS等加以处理,在Qt的线上文件中,有个QHttp的范例Http Example ,对QHttp的使用有更完整的示范。
******************************************************************************************
在Qt中使用QHttp下载带有?问号查询的Url地址内容(含源码 )
本站所有文章由本站和原作者保留一切权力,仅在保留本版权信息、原文链接、原文作者的情况下允许转载,转载请勿删改原文内容, 并不得用于商业用途。 谢谢合作。
原文链接:在Qt中使用QHttp下载带有?问号查询的Url地址内容(含源码 )
在<<C++ GUI Programming With Qt4>>这本书的第十四章介绍了用QHttp::get()函数去下载一个网页数据。但是这个例子只能处理常规的下载,也就是实现http请求中的“GET”请求,而不能实现”POST”请求。举例来说就是,QHttp::get()
能够下载 http://www.google.com/index.html 而不能下载 http://www.cuteqt.com/blog/?feed=rss 因为后者需要的下载方式不一样,可以用另外一个函数QHttp::request()来实现。
假如我们要执行上面第二个地址的请求,写出来的代码应该是下面的样子。
34 http.setHost("www.cuteqt.com/blog");
35 rssfile.setFileName("./feed.list");
36 rssfile.open(QIODevice::WriteOnly | QIODevice::Truncate);
37 QByteArray inputStr("feed=rss");
38 QHttpRequestHeader header("POST", "/blog/");
39 header.setValue("Content-Type", "application/x-www-form-urlencoded");
40 header.setValue("Host", "www.cuteqt.com/blog");
41 requestid=http.request(header,inputStr,&rssfile);
42 http.close();
34:http是QHttp 类型的,设置好要访问的主机
35:rssfile是QFile类型,下载的网页会存放到这个文件里
37:这个inputStr就是我们查询的串,格式可以是key1=var1&key2=var2&key3=var3的格式
38:设置好主机下的请求路径
40:header里的Host值,还是这个主机名
41:前面配置好的参数,正式发出请求,第三个参数类型是QIODevice *,如果不想存到文件里,你也可以用QBuffer。返回值requestid的作用下面会提到。
http.close();
需要注意的是,QHttp中不管是get()还是request()都是异步请求,也就是命令发出后,随即返回。在数据处理完毕的时候会有SIGNAL信号发出。request()处理完毕的信号名叫SIGNAL(requestFinished(int id,bool)),第一个参数id正是和前面request返回的requestid,以此知道是哪一个http请求处理后的返回消息。用以下函数关联信号和槽
connect(&http, SIGNAL(requestFinished(int,bool)), this, SLOT(httpReqDone(int,bool)));
通用代码如下:
QList<QPair<QByteArray, QByteArray> > querylist;
querylist=url.encodedQueryItems();
if(querylist.size()!=0)
{
QByteArray querydata;
querydata.append(querylist[0].first);
querydata.append('=');
querydata.append(querylist[0].second);
for (int i = 1; i < querylist.size(); ++i) {
querydata.append('&');
querydata.append(querylist[i].first);
querydata.append('=');
querydata.append(querylist[i].second);
}
QHttpRequestHeader header("POST", url.path());
header.setValue("Content-Type", "application/x-www-form-urlencoded");
header.setValue("Host", url.host());
http.setHost(url.host());
http_request_id=http.request(header,querydata,&file);
qDebug()<<querydata;
http.close();
}
else
{
http.setHost(url.host(), url.port(80));
http.get(url.path(), &file);
http_request_id=0;
http.close();
}
http://blog.csdn.net/mociml/article/details/5622126
相关文章推荐
- OkHttp解析
- Android NoHttp源码阅读指导
- 卷积神经网络——反向传播算法
- 卷积神经网络简介
- BP神经网络(完整的理论和经验公式)
- Vue.js学习系列三——axios和网络传输相关知识的学习实践
- OkHttp 3 的 Javadoc 翻译
- Python 网络抓取和文本挖掘-2 XML 和 JSON
- TensorFlow 深度学习笔记 从线性分类器到深度神经网络
- 使用python写神经网络模型之分类器
- 机器学习入门——初步认知人工神经网络
- 系统间通信:通过自定义协议通信加深HTTP理解
- 半数网站已用上HTTPS 你用上了吗(附转换教程)
- 解读神经网络十大误解,再也不会弄错它的工作原理
- 网络流isap
- 【java规则引擎】简单规则的rete网络示意图
- 第二章 ZeroMQ进阶
- Linux网络命令
- 用Let's Encrypt实现Https(Windows环境+Tomcat+Java)
- Android端和服务端Tomcat的https添加记录