http://hi.baidu.com/cmdmac/item/c45b9f0fb0d0938802ce1bbd

最近在搞QT跟服务器交互的东西,自然少不了发送和接受HTTP请求。
在网上找了一些资料知道以前的QT版本是使用QHTTP类来处理HTTP请求的,新版本是使用QNetworkAccessManager来进行管理的。

HTTP请求在QT中相应的类为QNetworkRequest,HTTP响应相应的类为QNetworkReply,下面是一个管理的发送HTTP请求并读取响应的例子:
//Test类代码段
//创建一个请求
QNetworkRequest request;
request.setUrl(QUrl("http://www.baidu.com"));
//创建一个管理器
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
QNetworkAccessManager *manager = new QNetworkAccessManager(this);
//发送GET请求
QNetworkReply *reply = manager->get(request);
//连接请求结束信号
connect(_networkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
//连接响应时返回数据信号
connect(reply, SIGNAL(readyRead()), this, SLOT(on_readyRead()));
......

void Test::replyFinished(QNetworkReply* reply)
{
QByteArray data = reply->readAll();
//这里会输出百度首页的HTML网页代码
qDebug() << data;
}

void Test::on_readyRead()
{
//....
}

上面是最简单的一个例子,事实上深入下去还会有很多的问题,这里分享一下我遇到的问题.第一个就是有关于QUrl类,这个是表示的是URL,使用默认的构造函数或者是它的setUrl函数会将设置的内容进行一次URL编码。看下面的例子:
QUrl url;
url.setUrl("http://www.baidu.com/api/uc.php?time=1284963040&code=a945GV5Ch23xWPOBQG%2Bq9MSX9hjoC2couTjpYjzln2q63ek1f3m9%2FCH31Z5OcWKn0Z0m3g5hOIPPRVhs2N%2FKeYX%2BB7BeJYW7rwAjsiEpDr8R0xGYLAAW0pLV9rC8pQYTOY46odZXMmbPfy4ExDbm2nNFvjj4jzkPdAd0Cxv0dRO4Sz50");
QNetworkRequest request;
request.setUrl(url);
QNetworkAccessManager *manager = new QNetworkAccessManager();
manager->get(request);

再把setUrl换成setEncodedUrl,即如下:
QUrl url;
url.setEncodedUrl("http://www.baidu.com/api/uc.php?time=1284963040&code=a945GV5Ch23xWPOBQG%2Bq9MSX9hjoC2couTjpYjzln2q63ek1f3m9%2FCH31Z5OcWKn0Z0m3g5hOIPPRVhs2N%2FKeYX%2BB7BeJYW7rwAjsiEpDr8R0xGYLAAW0pLV9rC8pQYTOY46odZXMmbPfy4ExDbm2nNFvjj4jzkPdAd0Cxv0dRO4Sz50");
qDebug() << url;

QNetworkRequest request;
request.setUrl(url);
QNetworkAccessManager *manager = new QNetworkAccessManager();
manager->get(request);
上面的URL虽然是乱写的,但是通过HTTP抓包工具可以看到两者发出的HTTP请求是不一样的。
下面是通过WireShark软件抓到的HTTP数据包,前者发送的请求是这样的:

而后者是这样的:

注意图片里两个红色框内的数据,它们是不一样的,显然后者跟代码里的URL设置的是一样的,而前者有所改变,这就是URL对它进行再一次URL编码了,在URL中%号会被编码成%25,所以我会看到红色框中的%wBq9变成了%252Bq9多了25两个字符。

这个问题困扰了我两天,最后才发现这个问题,因为如果URL没有%号这样特殊字符的时候,进行再一次的编码后还是一样的,但发送的请求却是不一样的,即使在WireShark上看是一样的。

另外一个问题是关于COOKIE的问题,当你用WEBVIEW用load方法加载一个Request,而在这个请求中加入了COOKIE和能完成跟服务器的交互,而加载完后的网页不会在本地保存服务器返回的COOKIE,当你在网页中如点击一个链接发送一个请求时,这时发送请求不会带上之前你带的上COOKIE,这需要你为那个PAGE设置QNetworkAccessManager,并且设置它的QNetworkCookieJar,这样的话,以后无论怎么发送请求,QT都会自动把COOKIE带上,不用每次都用加载一个Request的方法发送请求了。
示例代码如下:
void Test::initPage(QWebPage* page)
{
if (page != NULL)
{
page->setNetworkAccessManager(instance()->_networkManager);
}
}

//设置cookieJar
this->_networkManager->cookieJar()->setCookiesFromUrl(newCookies, QUrl("http://www.baidu.com/"));

Qt发送HTTP请求的更多相关文章

  1. Qt 发送 https 请求

    1.环境 ubuntu 12.04 Qt库版本 4.8.1(安装包是Nokia时期的sdk,现在已经不好找了) 2.网上一查都说 Qt 默认不支持Openssl,心想那https也肯定用不了啊,然后屁 ...

  2. 使用Qt发送HTTPS请求

    示例代码: #include "mainwindow.h" #include "ui_mainwindow.h" #include <QNetworkAc ...

  3. Qt 之 使用 https发送 HTTP请求(使用OPENSSL库)

    一.简述 在使用Qt发送HTTP请求中一般使用的链接都是http://前缀,而有的服务器支持 https://前缀的链接,而Qt本身是支持https的,但是https访问需要用到SSL认证,而QT默认 ...

  4. QT之Http请求

    今天我们介绍一下QT的http请求,这里有post和get两种方式 一.post请求方式:参数分为网址和具体请求值两个部分,有时候还需要设置头信息,看具体情况定 void MainWindow::se ...

  5. Java发送Http请求并获取状态码

    通过Java发送url请求,查看该url是否有效,这时我们可以通过获取状态码来判断. try { URL u = new URL("http://10.1.2.8:8080/fqz/page ...

  6. AngularJs的$http发送POST请求,php无法接收Post的数据解决方案

      最近在使用AngularJs+Php开发中遇到php后台无法接收到来自AngularJs的数据,在网上也有许多解决方法,却都点到即止.多番摸索后记录下解决方法:tips:当前使用的AngularJ ...

  7. Ajax发送POST请求SpringMVC页面跳转失败

    问题描述:因为使用的是SpringMVC框架,所以想使用ModelAndView进行页面跳转.思路是发送POST请求,然后controller层中直接返回相应ModelAndView,但是这种方法不可 ...

  8. 使用HttpClient来异步发送POST请求并解析GZIP回应

    .NET 4.5(C#): 使用HttpClient来异步发送POST请求并解析GZIP回应 在新的C# 5.0和.NET 4.5环境下,微软为C#加入了async/await,同时还加入新的Syst ...

  9. 在发送ajax请求时加时间戳或者随机数去除js缓存

    在发送ajax请求的时候,为了保证每次的都与服务器交互,就要传递一个参数每次都不一样,这里就用了时间戳 大家在系统开发中都可能会在js中用到ajax或者dwr,因为IE的缓存,使得我们在填入相同的值的 ...

随机推荐

  1. 用过的正则(更新ing)

    http://www.debuggex.com/   这个很好用20120912 //十六进制颜色值的正则表达式 var reg = /^#([0-9a-fA-f]{3}|[0-9a-fA-f]{6} ...

  2. 实验三 敏捷开发与XP实践(改)

    ---恢复内容开始--- 一.敏捷开发与XP 二.编码标准 1.编码标准中的版式就是一个很好的例子,版式虽然不会影响程序的功能,但会影响可读性.程序的版式追求清晰.美观,是程序风格的重要因素.单击Ec ...

  3. 关于PATH_INFO SCRIPT_NAME SCRIPT_FILENAME REDIRECT_URL 详解

    参考:http://www.nginx.cn/426.html  http://www.cnblogs.com/xiaochaohuashengmi/archive/2011/09/13/217507 ...

  4. RedHat 安装MySQL数据库【转】

      朋友购买了阿里云的服务器,服务器上自带有CentOS操作系统,但是开发软件需要自己安装,接下来将介绍本地RedHat Linux 5.10虚拟机上搭建Mysql数据库. 一.软件准备 (1)jdk ...

  5. [整][转]Invoke和BeginInvoke的使用

    在Invoke或者BeginInvoke的使用中无一例外地使用了委托Delegate. 一.为什么Control类提供了Invoke和BeginInvoke机制? 关于这个问题的最主要的原因已经是do ...

  6. 复利计算4.0单元测试(c语言)

    ——————————复利计算程序单元测试报告—————————— ————————————4.0 单元测试—————————————— ————————————————要求—————————————— ...

  7. sqlite多表关联update

    sqlite数据库的update多表关联更新语句,和其他数据库有点小不一样 比如:在sql server中: 用table1的 id 和 table2的 pid,关联table1 和 table2 , ...

  8. cmd打开控制面板及其他命令

    如果你在权限较小的域用户的机器上,要做一些管理操作,就不可避免的要使用cmd打开一些以前只能在图形界面里打开的程序.下面是我收集的一些常用操作. 以某个身份启动程序:runas /user:it\n1 ...

  9. 数据结构-AVL树的旋转

    http://blog.csdn.net/GabrieL1026/article/details/6311339 平衡二叉树在进行插入操作的时候可能出现不平衡的情况,AVL树即是一种自平衡的二叉树,它 ...

  10. include指令和<jsp:include>标准动作

    利用JSP的包含机制,可以有效的避免重复,把可重用的部分独立出去,使用include把它们包含到当前文件.JSP有两种包含机制:include指令和<jsp:include>标准动作. 1 ...