卷曲错误18-传输关闭,剩余未读数据


70

使用curl从URL检索数据时,有时(在80%的情况下)

错误18:传输关闭,剩余未完成的读取数据

然后缺少部分返回的数据。奇怪的是,当CURLOPT_RETURNTRANSFER设置为false时,这永远不会发生,即curl_exec函数不会返回数据而是直接显示内容。

可能是什么问题呢?我可以设置一些选项来避免这种行为吗?


您能给我们您尝试使用的URL吗,如果您在本地主机上对其进行测试,则可能是一个错误的连接。
问号,

1
您要发送Connection: Close标题吗?如果是这样,请尝试使用Connection: Keep-AliveKeep-Alive: ***而***是您可以选择的数字(为了安全起见,可能为10秒;大多数现代浏览器使用300,即5分钟)。
09年

Answers:


35

我敢打赌这与Content-Length同行发送的错误标题有关。我的建议是让curl自行设置长度。


5
它可以与Content-Length响应头相关。我在一个同事项目中遇到了类似的情况:Java Web服务网关设置Content-Length:601,而XML响应为210字节
pcdinh 2010年

我相信@pcdinh是正确的。我们使用无终止的分块传输编码得到了相同的结果。curl期望更多数据(服务器宣布发送更多或未发送终止0),但服务器关闭连接。
iGEL

2
没有附带的“内容长度”,附带示例。
MariuszS 2013年

1
你们是如何解决这个问题的?我没有在代码中发送任何内容长度。是从服务器端自动添加的东西吗?
Mijoe

47

错误字符串完全就是libcurl看到的内容:由于它正在接收分块的编码流,因此它知道何时在分块中还有剩余的数据要接收。关闭连接后,libcurl知道最后收到的块不完整。然后,您得到此错误代码。

您无法采取任何措施来避免在未修改请求的情况下发生此错误,但是您可以尝试通过发出HTTP 1.0请求来解决该错误(因为此时不会进行分块编码),但事实是,这很可能是一个缺陷在服务器或您的网络/设置中。


1
对我来说,问题出在我无法控制的远程,唯一可行的解​​决方法是强制使用1.0:curl_setopt($ curl,CURLOPT_HTTP_VERSION,CURL_HTTP_VERSION_1_0);
埃里克·卡隆

@DanielStenberg仍然是同样的问题。

设定HTTP版本 1.0帮助我处理了分块编码和在检索到的数据中出现奇怪的十六进制标记的问题。非常感谢这个提示!
Givi

我们使用curl的特定URL是否会发生某些情况?@EricCaron
莫娜·贾拉勒

@MonaJalal我没有运行远程服务器,所以我不知道它的配置。我的猜测是IIS具有不同的配置,并且对1.0和1.1请求的响应不同。
埃里克·卡隆

7

我遇到了同样的问题,但是设法通过抑制cURL通常发送的“期望:100-继续”标头来解决(以下是PHP代码,但应该与其他cURL API相似地工作):

curl_setopt($curl, CURLOPT_HTTPHEADER, array('Expect:'));

顺便说一句,我正在将调用发送到JDK 6 REST内容中包含的HTTP服务器,这会遇到各种问题。在这种情况下,它首先发送100响应,然后对某些请求不能正确发送后续的200响应。


我们将在哪里修改此设置?我只是不知道cURL在Windows中时在何处添加此行。
DomainsFeatured '17

1
@DomainsFeatured我不确定“ cURL在Windows中”是什么意思,但是在命令行上,您可以通过为它提供一个空值来禁止显示“期望:”标头:curl -H 'Expect:' ...希望对您
有所

我在IIS上运行wordpress,它使用cURL,所以我不知道在何处指定此选项:-/
DomainsFeatured

我不知道很多关于WordPress的,但它是开源的,所以你应该能够找到PHP代码的相关部分,基本上只需插入从我的回答行(改变名称后可能$curl到任何它被称为在码)。
jcsahnwaldt恢复莫妮卡的时间

我有点困惑,“ Expect:100”标头用于服务器鼓励客户端发送数据,而不用于客户端接收数据。如何取消此标头可以帮助客户端接收数据?谢谢。
Joey Sun

7

在使用Guzzle时也会看到此错误。以下标头为我修复了该标头:

'headers' => [
    'accept-encoding' => 'gzip, deflate',
],

我向邮递员发出了请求,这给了我完整的答复,没有错误。然后,我开始添加Postman发送到Guzzle请求的标头,而这正是解决该问题的标头。


谢谢,这对我有用。我尝试与邮递员获取响应标头,发现响应返回gzip,所以我添加了它。
Parminder Singh,

3

当我的服务器进程在生成响应期间中途遇到异常,并且只是简单地关闭了连接而没有说再见时,我收到了此错误。卷曲从连接仍然期望的数据,并抱怨(理所当然)。



1

我已经通过这种方式解决了这个错误。

$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;

错误仍然会发生,但是我可以处理变量中的响应数据。


1

当我不小心将文件下载到其自身时,出现此错误。
(我已经在远程目录的sshfs挂载中创建了一个符号链接,以使其可供下载,忘记了切换工作目录,并使用了它-OJ)。

我想当您阅读本文时,它实际上并不会“帮助”您,因为这意味着您的文件已被破坏。


1

遇到类似的问题,我的服务器在nginx后面。Web服务器(Python flask)日志中没有错误,但是nginx日志中有一些错误消息。

[crit] 31054#31054:* 269464 open()“ / var / cache / nginx / proxy_temp / 3/45/0000000453”失败(13:权限被拒绝),同时读取上游

我通过更正目录权限解决了此问题:

/var/cache/nginx
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.