【问题标题】:How to properly do a http GET request using QNetworkAccessManager and QNetworkReply? How does the URL affect the request in Qt?如何使用 QNetworkAccessManager 和 QNetworkReply 正确执行 http GET 请求? URL 如何影响 Qt 中的请求?
【发布时间】:2017-10-13 07:40:47
【问题描述】:

这是对this 问题的跟进。起初我认为在查看example from the Qt wiki 后问题已经解决(我使用相同的代码,没有进行任何更改)。但是,罪魁祸首似乎是 URL。我尝试使用this 答案中提供的链接来测试我的 http GET 请求。使用 Http Requester(用于 Http 请求(GET、POST 等)的 Firefox 插件)和curl 显示此链接没有问题^:

$~: curl --request GET --url "http://httpbin.org/ip" 

由于某种原因,Qt 卡住了,并且永远不会发出 readyRead()/finished() 信号。

因此,由于套接字超时,请求在一段时间后被取消......对于非常小的东西,Firefox 在不到一秒的时间内打开。

在 Http 方面,我远非专家。我想知道为什么在 Qt 中会出现这种行为,而在使用其他工具时却没有。

编辑:我还使用 Python 及其 urllib

测试了有问题的 URL
import urllib.request
res = urllib.request.urlopen("http://httpbin.org/ip").read().decode("utf-8") 

import xml.etree.ElementTree as ET
doc = ET.fromstring(res)

它工作得很好。很明显,Qt 正在运行和/或我在使用它时遗漏了一些东西。

EDIT2:我还尝试了另一种 HTTP 请求测试服务 - https://postman-echo.com。用curl没问题:

$~: curl --request GET --url "https://postman-echo.com/get?foo1=bar1&foo2=bar2"

令我惊讶的是,Qt 也没有问题!我在这里看到的唯一巨大差异是postman-echo.com 使用HTTPS,而我尝试过的其他URL 是HTTP。我排除了 https://www.qt.io,它是 Qt 示例中的默认 URL,并且工作得很好(尽管它没有任何参数)。

【问题讨论】:

  • 您仍然需要展示您的代码以帮助我们理解问题。
  • @vahancho 我使用来自 Qt wiki 的完全相同的代码。没有改变任何一行。
  • 为了找到问题的根本原因,您必须回答以下问题:1) 我的应用程序是否发送正确的请求?,2) 应用程序是否从服务器获得响应? 3) 应用程序是否正确处理从服务器获得的响应?
  • 该示例适用于我尝试过的许多其他 URL,包括下载大文件(如 Ubuntu 17.04 的 ISO 映像),这意味着在 general 中它确实发送了正确的请求,从服务器获取响应并毫无问题地处理它。但是,在我上面描述的情况下,我不知道如何检查是否发送了正确的请求。我确实知道事情是异步工作的,所以我确实希望从服务器获得响应会有延迟。
  • 您在向该服务器发送请求后是否处理错误?服务器可能会尝试识别“谁”发送请求,如果未知,则拒绝正确响应。你也可以检查一下这个想法。

标签: c++ qt http url http-get


【解决方案1】:

尝试在事件循环中执行它。这与我在非 gui 应用程序中所做的类似:

QUrl req_url = QUrl(href);
QNetworkRequest request(req_url);

//request.setRawHeader("Content-Type", "application/json;utf8");
//q_nam is QNetworkAccessManager created earlier
QNetworkReply *reply = q_nam->get(request);

QEventLoop event_loop;
connect(q_nam, SIGNAL(finished(QNetworkReply * ) ), &event_loop, SLOT(quit() ) );
event_loop.exec(); // blocks stack until "finished()" has been called
event_loop.processEvents(QEventLoop::ExcludeUserInputEvents, 500 );//what events to processed and for how long
event_loop.exit();

QNetworkReply::NetworkError er = reply->error();
// ....continue handling

【讨论】:

  • 不起作用,我仍然得到套接字超时。此外,来自 Qt wiki 的示例实际上是一个小部件,但感谢您的努力。我自己的应用程序将基于控制台,所以很高兴知道我也需要它。
  • 只是为了确保我做对了 - URL 是 http://bvg.hafas.de/bin/monitor_hci/stboard.exe/dn?input=9054102&start=1&output=xml ?
  • 两者都不起作用 - httpbin.org 和来自 bvg.hafas.de 的那个。我已经使用许多其他 URL 测试了该应用程序,并且没有遇到问题。但是这两个……我不知道。
  • 啊,我想我必须使用QUrlQuery,因为这些网址实际上也包含参数。 掌心
  • :) 告诉我进展如何
【解决方案2】:

我忘了说我落后了。坦率地说,我错过了这一点,也没有通过工作中的访客网络进行检查(这绕过了愚蠢的代理),我感到相当愚蠢。我的一位同事尝试使用 HTTPS 而不是 HTTP(这是原始链接)。 HTTPS 也是代理可以毫无问题地通过的东西。它奏效了。

然而,更中立的解决方案是(正如我的同事发现的那样)使用QNetworkProxyFactory::setUseSystemConfiguration(true),它采用我在系统范围内拥有的代理配置。

【讨论】:

    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    • 1970-01-01
    相关资源
    最近更新 更多