使用curl从URL检索数据时,有时(在80%的情况下)会出现错误18:传输关闭但仍存在未读数据。于是返回的一部分数据丢失了。奇怪的是,当CURLOPT_RETURNTRANSFER设置为false时,即curl_exec函数不返回数据而直接显示内容时,这种情况永远不会发生。
可能的问题是什么?我能设置某些选项以避免此类行为吗?
错误字符串就是libcurl所看到的内容:因为它正在接收块编码流,所以它知道何时还有数据要接收。当连接关闭时,libcurl知道上一个接收到的块不完整。然后你会得到这个错误代码。
如果请求未被修改,你无法避免此错误,但你可以尝试通过发出HTTP 1.0请求来解决此问题(因为那时不会发生块编码),但事实上,这很可能是服务器或你的网络/设置中的缺陷。
我猜这可能与对等方发送的错误的Content-Length
头有关。我的建议是让curl自己设置长度。
Content-Length
头也可以由服务器正确设置;但是可能会发生服务器截断响应的情况,因此它不会发送所有“承诺”的内容长度,这是由于生成/发送响应的脚本(例如 PHP 脚本)崩溃所致。请参见另一个问题的此响应:https://dev59.com/EOk6XIcBkEYKwwoYEP3x#76217574。 - nickshoe在使用 Guzzle 的过程中也遇到了这个错误。以下的报文头对我有帮助:
看到这个错误
在使用 Guzzle 的过程中也遇到了这个错误。以下的报文头对我有帮助:
'headers' => [
'accept-encoding' => 'gzip, deflate',
],
我使用Postman发出请求,得到了完整的响应和没有错误。然后我开始添加Postman发送到Guzzle请求的标头,这是修复问题的其中一个。
我曾经遇到过同样的问题,但是通过取消cURL发送的“Expect:100-continue”标头(以下是PHP代码,但应该与其他cURL API类似)成功解决了:
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));
顺便提一下,我正在向JDK 6 REST中包含的HTTP服务器发送调用,但它存在各种问题。在这种情况下,它首先发送100响应,然后在某些请求中无法正确发送随后的200响应。
curl -H 'Expect:' ...
希望这能帮到你... - jcsahnwaldt Reinstate Monica$curl
的名称更改为该代码中使用的名称)。 - jcsahnwaldt Reinstate Monica在生成响应期间,我的服务器进程遇到异常并且没有正常关闭连接,因此突然关闭了连接。curl仍然期望从连接获得数据并抱怨(无可厚非)。
遇到了类似的问题,我的服务器在nginx后面。 Web服务器(Python Flask)日志中没有错误,但是nginx日志中有一些错误消息。
[crit] 31054#31054: * 269464 open()“/var/cache/nginx/proxy_temp/3/45/0000000453”失败(13:权限被拒绝),同时读取upstream
我通过更正目录权限来解决这个问题:
/var/cache/nginx
nginx
作为用户ID daemon
运行,而不是 nginx
-> nginx.conf:user nginx;
... 我的操作系统(Alpine)软件包安装假定您将以用户 nginx
而不是 daemon
运行 nginx
。更改权限可能也可以解决问题,但在我的情况下,以 nginx
的身份运行更好。 - James Stevens当我的服务器磁盘空间已满并在生成响应期间中途关闭连接时,我遇到了这个错误,并且只是关闭了连接。
我在使用pycurl时遇到了这个问题,我通过以下方式解决了它
c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0)
就像Eric Caron所说的那样。
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, 'http://www.someurl/' );
curl_setopt ( $ch, CURLOPT_TIMEOUT, 30);
ob_start();
$response = curl_exec ( $ch );
$data = ob_get_clean();
if(curl_getinfo($ch, CURLINFO_HTTP_CODE) == 200 ) success;
-OJ
)
Connection: Close
头?如果是的话,尝试使用类似于Connection: Keep-Alive
和Keep-Alive: ***
的内容,其中 *** 是您选择的有意义的数字(也许安全起见选择10秒;大多数现代浏览器使用300,即5分钟)。 - Dereleased