如何使用 QNetworkAccessManager 和 QNetworkReply 正确执行 http GET 请求? URL 如何影响 Qt 中的请求?
How to properly do a http GET request using QNetworkAccessManager and QNetworkReply? How does the URL affect the request in Qt?
这是 question. At first I thought the issue was resolved after checking out the example from the Qt wiki (I use the same code without a single change). However it appears that it's the URL that is the culprit. I tried using the links provided in this 回答的跟进,用于测试我的 http GET 请求。使用 Http Requester(用于 Http 请求(GET、POST 等)的 Firefox 插件)和 curl
显示此 link^:
没有问题
$~: curl --request GET --url "http://httpbin.org/ip"
由于某种原因,Qt 卡住了,readyRead()
/finished()
信号永远不会发出。
因此,由于套接字超时,请求在一段时间后被取消...对于非常小的东西,Firefox 在不到一秒的时间内打开。
在 Http 方面,我远不是专家。我想知道为什么在 Qt 中会出现这种行为,而在使用其他工具时却没有任何迹象。
编辑: 我还使用 Python 及其 urllib
测试了有问题的 URLs
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 有一些问题 and/or 我在使用它时遗漏了一些东西。
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,而我尝试过的其他 URLs 是 HTTP。我排除了 Qt 示例中默认的 https://www.qt.io
URL 并且工作得很好(尽管它没有任何参数)。
尝试在事件循环中执行它。这与我在非图形用户界面应用程序中所做的类似:
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
我忘了说我落后了。坦率地说,我觉得很愚蠢,因为错过了这个,也没有检查工作中的访客网络(绕过了愚蠢的代理)。我的一位同事尝试使用 HTTPS 而不是 HTTP(这是原始的 link)。 HTTPS 也是代理允许通过而没有任何问题的东西。它奏效了。
然而,更中性的解决方案是(正如我的同事发现的那样)使用 QNetworkProxyFactory::setUseSystemConfiguration(true)
,它采用我在系统范围内的代理配置。
这是 curl
显示此 link^:
$~: curl --request GET --url "http://httpbin.org/ip"
由于某种原因,Qt 卡住了,readyRead()
/finished()
信号永远不会发出。
因此,由于套接字超时,请求在一段时间后被取消...对于非常小的东西,Firefox 在不到一秒的时间内打开。
在 Http 方面,我远不是专家。我想知道为什么在 Qt 中会出现这种行为,而在使用其他工具时却没有任何迹象。
编辑: 我还使用 Python 及其 urllib
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 有一些问题 and/or 我在使用它时遗漏了一些东西。
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,而我尝试过的其他 URLs 是 HTTP。我排除了 Qt 示例中默认的 https://www.qt.io
URL 并且工作得很好(尽管它没有任何参数)。
尝试在事件循环中执行它。这与我在非图形用户界面应用程序中所做的类似:
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
我忘了说我落后了。坦率地说,我觉得很愚蠢,因为错过了这个,也没有检查工作中的访客网络(绕过了愚蠢的代理)。我的一位同事尝试使用 HTTPS 而不是 HTTP(这是原始的 link)。 HTTPS 也是代理允许通过而没有任何问题的东西。它奏效了。
然而,更中性的解决方案是(正如我的同事发现的那样)使用 QNetworkProxyFactory::setUseSystemConfiguration(true)
,它采用我在系统范围内的代理配置。