当使用curl从URL检索数据时,我有时(在80%的情况下)得到
错误18:传输已关闭但仍有未完成的读取数据
然后丢失部分返回的数据。奇怪的是,当CURLOPT_RETURNTRANSFER设置为false时,这种情况永远不会发生,即curl_exec函数不返回数据但直接显示内容。
可能是什么问题?我可以设置一些选项来避免这种行为吗?
答案 0 :(得分:42)
错误字符串非常简单地说就是libcurl所看到的:因为它正在接收一个分块编码流,所以它知道什么时候要在一个块中留下数据来接收。当连接关闭时,libcurl知道最后收到的块是不完整的。然后你得到这个错误代码。
在没有修改请求的情况下,你无法做任何事情来避免这个错误,但你可以尝试通过发出HTTP 1.0请求来解决它(因为那时不会发生chunked编码)但是事实是,这很可能是服务器或网络/设置中的一个缺陷。
答案 1 :(得分:25)
我敢打赌,这与对等方发送的错误Content-Length
标头有关。
我的建议是让curl自己设定长度。
答案 2 :(得分:5)
我遇到了同样的问题,但设法通过抑制cURL通常发送的'Expect:100-continue'标头来修复它(以下是PHP代码,但应该与其他cURL API类似):
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));
顺便说一下,我正在向JDK 6 REST中包含的HTTP服务器发送调用,这有很多问题。在这种情况下,它首先发送100响应,然后对某些请求不会正确发送后续200响应。
答案 3 :(得分:1)
当我的服务器进程在生成响应期间中途遇到异常并且只是在没有说再见的情况下关闭连接时,我收到此错误。 curl仍然期待来自连接的数据并抱怨(理所当然)。
答案 4 :(得分:1)
我在使用pycurl时遇到了这个问题,我使用
解决了这个问题c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0)
就像Eric Caron所说的那样。
答案 5 :(得分:1)
遇到类似的问题,我的服务器在nginx后面。 Web服务器(Python flask)日志中没有错误,但是nginx日志中有一些错误消息。
[crit] 31054#31054:* 269464 open()“ / var / cache / nginx / proxy_temp / 3/45/0000000453”失败(13:权限被拒绝)
我通过更正目录权限解决了此问题:
/var/cache/nginx
答案 6 :(得分:0)
我通过这种方式解决了这个错误。
$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;
错误仍然存在,但我可以处理变量中的响应数据。
答案 7 :(得分:0)
我不小心将文件下载到其自身时出现了此错误。
(我已经在远程目录的sshfs挂载中创建了一个符号链接,以使其可供下载,忘记了切换工作目录,并使用了-OJ
)。
我想当您阅读本文时,它并不会真正帮助您,因为这意味着您的文件已被破坏。
答案 8 :(得分:0)
在使用Guzzle时也会看到此错误。以下标头为我修复了该问题:
'headers' => [
'accept-encoding' => 'gzip, deflate',
],
我向邮递员发出了请求,这给了我完整的答复,没有错误。 然后,我开始添加Postman发送到Guzzle请求的标头,这就是修复标头的标头。
答案 9 :(得分:0)
当我的服务器用完磁盘空间并在生成响应期间中途关闭连接并简单地关闭连接时,我收到此错误
答案 10 :(得分:0)
我在通过 nginx
代理运行时遇到此错误,并且我在用户 ID nginx
而不是用户 ID daemon
下运行 nginx
。
这意味着某些 nginx 的临时目录不可访问/可写。
从 user daemon;
切换到 user nginx;
为我解决了这个问题。
答案 11 :(得分:0)
我遇到了同样的问题。我尝试了所有这些解决方案,但没有一个奏效。就我而言,该请求在 Postman 中运行良好,但是当我在 php 中使用 curl 执行此操作时,出现上述错误。
我所做的是检查 Postman 生成的 PHP 代码并复制相同的内容。
首先将请求设置为使用 Http 1.1 版 第二个最重要的部分是我的编码。
这是帮助我的代码
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
如果我删除 CurlOpt 编码,我会返回错误。