Php 卷曲错误18-传输已关闭,剩余未完成的读取数据

Php 卷曲错误18-传输已关闭,剩余未完成的读取数据,php,curl,Php,Curl,当使用curl从URL检索数据时,我有时(在80%的情况下)会 错误18:传输已关闭,未完成的读取数据仍保留 然后,返回的部分数据丢失。奇怪的是,当CURLOPT_RETURNTRANSFER设置为false时,这永远不会发生,也就是说curl_exec函数不返回数据,而是直接显示内容 有什么问题吗?我可以设置一些选项来避免这种行为吗?我打赌这与对等方发送的错误的内容长度标题有关。 我的建议是让curl自己设置长度 我也遇到了同样的问题,但通过抑制cURL通常发送的'Expect:100 con

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

错误18:传输已关闭,未完成的读取数据仍保留

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


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

我打赌这与对等方发送的错误的
内容长度
标题有关。
我的建议是让curl自己设置长度

我也遇到了同样的问题,但通过抑制cURL通常发送的'Expect:100 continue'头(以下是PHP代码,但应与其他cURL API类似):


顺便说一下,我正在向JDK 6 REST中包含的HTTP服务器发送调用,它有各种各样的问题。在这种情况下,它首先发送一个100响应,然后在一些请求中没有正确地发送随后的200响应。

错误字符串与libcurl看到的完全相同:因为它正在接收一个分块编码流,所以它知道分块中何时还有数据要接收。当连接关闭时,libcurl知道最后接收到的块是不完整的。然后你会得到这个错误代码


在未修改请求的情况下,您无法避免此错误,但您可以尝试通过发出HTTP 1.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;

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

当我的服务器进程在生成响应的中途出现异常时,我遇到了这个错误,只是在不说再见的情况下关闭了连接。curl仍然期望从连接中获得数据,并抱怨(正确)。

我在使用pycurl时遇到了这个问题,我使用

c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0) 

就像说的那样。

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


我想当你读到这篇文章时,它不会真的对你有帮助,因为它意味着你的文件被破坏了

在使用Guzzle时也会看到这个错误。下面的标题为我修复了它:

'headers' => [
    'accept-encoding' => 'gzip, deflate',
],
我向邮递员发出了请求,邮递员给了我一个完整的回复,没有错误。
然后我开始添加Postman发送给Guzzle请求的头,这就是修复它的头。

遇到类似问题,我的服务器支持nginx。 web服务器(PythonFlask)日志中没有错误,但nginx日志中有一些错误消息

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

我通过更正目录的权限修复了此问题:

/var/cache/nginx

当我的服务器磁盘空间不足,在生成响应的过程中中途关闭了连接,并简单地关闭了连接时,我出现了这个错误。我在通过
nginx
代理运行时出现了这个错误,我在用户id
守护进程下运行
nginx
,而不是在用户id
nginx
下运行

这意味着nginx的一些临时目录无法访问/写入


用户守护进程切换
用户nginx为我修复了它。

我也有同样的问题。我尝试了所有这些解决方案,但没有一个奏效。在我的例子中,请求在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编码,我会返回错误。

你能告诉我们你正在尝试的URL吗?如果你在本地主机上测试这个,可能是一个坏连接。你正在发送
连接:关闭
头吗?如果是这样,请尝试使用类似于
Connection:Keep-Alive
Keep-Alive:**
的方法,其中***是您选择的有意义的数字(为了安全起见,可能是10秒;大多数现代浏览器使用300,也就是5分钟)。它可能与内容长度响应标题有关。我在一个同事的项目中遇到过类似的情况:JavaWebService网关将内容长度设置为601,而XML响应为210字节,我相信@pcdinh是正确的。我们用一个未终止的分块传输编码得到了同样的结果。curl需要更多数据(服务器宣布发送更多数据或未发送终止的0),但服务器关闭了连接。没有包含“内容长度”,示例已附加。你们是如何解决此问题的?我不发送任何内容长度的代码。它是从服务器端自动添加的吗?对我来说,问题是在一个我无法控制的远程端,唯一有效的修复方法是强制使用1.0:curl_setopt($curl,CURLOPT_HTTP_VERSION,curl_HTTP_VERSION_1_0)@DanielStenberg仍然存在同样的问题。设置HTTP版本。1.0帮助我在检索到的数据中出现分块编码和奇怪的十六进制标记。非常感谢你的提示!对于我们使用curl的特定URL,是否会发生这种情况@EricCaron@MonaJalal我没有运行远程服务器,所以我不知道它的配置。我猜IIS有不同的配置,对1.0和1.1请求的响应也不同。我们应该在哪里修改此设置?当cURL在Wi中时,我不知道在哪里添加这条线
curl_setopt($ch, CURLOPT_ENCODING, '');
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);