zoukankan      html  css  js  c++  java
  • Qt发送HTTP请求

    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/"));

  • 相关阅读:
    angular $apply()以及$digest()讲解1
    AngularJs + Bootstrap
    angular service讲解
    末班方法代码实战和总结
    JS基础学习1——什么是基础js类和原型?
    背景图片background-size兼容ie8以下浏览器解决
    magento2 客户端模式less样式修改。
    git贡献代码流程
    React模板
    获取iframe src中参数
  • 原文地址:https://www.cnblogs.com/Travis990/p/4483538.html
Copyright © 2011-2022 走看看