【问题标题】:curl error 18 - transfer closed with outstanding read data remainingcurl 错误 18 - 传输已关闭,剩余未完成的读取数据
【发布时间】:2010-12-18 02:43:03
【问题描述】:

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

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

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

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

【问题讨论】:

  • 你能给我们你正在尝试的 URL,如果你在你的本地主机上测试它可能是一个错误的连接。
  • 您是否发送Connection: Close 标头?如果是这样,请尝试使用 Connection: Keep-AliveKeep-Alive: *** 之类的东西,其中 *** 是您选择的有意义的数字(可能是 10 秒,为了安全起见;大多数现代浏览器使用 300,即 5 分钟)。跨度>

标签: php curl


【解决方案1】:

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

您无法在未修改请求的情况下避免此错误,但您可以尝试通过发出 HTTP 1.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 请求的响应也不同。
【解决方案2】:

我敢打赌,这与对等方发送的错误 Content-Length 标头有关。 我的建议是让 curl 自己设置长度。

【讨论】:

  • 可以和Content-Length响应头有关。我在一个同事项目中遇到过类似的情况:Java Web 服务网关设置 Content-Length: 601 而 XML 响应为 210 字节
  • 我相信@pcdinh 是对的。我们使用未终止的分块传输编码得到了相同的结果。 curl 期待更多数据(服务器宣布发送更多或不发送终止 0),但服务器关闭连接。
  • 不包含“Content-Length”,附上示例。
  • 你们是如何解决这个问题的?我没有在代码中发送任何内容长度。它是从服务器端自动添加的吗?
【解决方案3】:

在使用 Guzzle 的过程中也看到了这个错误。以下标题为我修复了它:

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

我向 Postman 发出了请求,它给了我完整的响应并且没有错误。 然后我开始添加 Postman 发送到 Guzzle 请求的标头,这就是修复它的标头。

【讨论】:

  • 谢谢,这对我有用。我尝试使用邮递员获取响应标头,发现响应返回的是 gzip,所以我添加了这个。
  • 这有所帮助,但是响应变成了 gzip 格式。
  • 这也解决了我的 Insomnia 问题和使用大型数据集查询 Lumen API。
【解决方案4】:

我遇到了同样的问题,但设法通过抑制 cURL 通常发送的 'Expect: 100-continue' 标头来解决它(以下是 PHP 代码,但应该与其他 cURL API 类似地工作):

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

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

【讨论】:

  • 我们应该在哪里修改这个设置?当 cURL 在 Windows 中时,我只是不知道在哪里添加这一行。
  • @DomainsFeatured 我不确定您所说的“cURL 在 Windows 中”是什么意思,但是在命令行上,您可以通过给它一个空值来抑制“期望:”标题:@987654322 @我希望这会有所帮助...
  • 我在 IIS 上运行 wordpress,它使用 cURL,所以我不知道在哪里指定这个选项:-/
  • 我对 WordPress 了解不多,但它是开源的,所以您应该能够找到 PHP 代码的相关部分,基本上只需插入我的答案中的行(可能在更改$curl 的名称到该代码中的任何名称)。
  • 我有点糊涂了,“Expect:100”是服务端用来鼓励客户端发送数据的,而不是客户端接收数据的。如何隐藏这个头可以帮助客户端接收数据?谢谢。
【解决方案5】:

当我的服务器进程在生成响应过程中遇到异常并且没有说再见就简单地关闭了连接时,我收到了这个错误。 curl 仍然期望来自连接的数据并抱怨(正确地)。

【讨论】:

    【解决方案6】:

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

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

    我通过更正目录的权限解决了这个问题:

    /var/cache/nginx
    

    【讨论】:

    • 我也有这个问题。这是由于运行 nginx 作为用户 ID daemon 而不是 nginx -> nginx.conf:user nginx; ...我的 O/S (Alpine) 软件包安装假定您将以用户 @987654327 的身份运行 nginx @不是daemon。更改权限可能也可以修复它,但恕我直言,以nginx 运行是一个更好的解决方法 - 对于我的情况
    【解决方案7】:

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

    解决了它
    c.setopt(pycurl.HTTP_VERSION, pycurl.CURL_HTTP_VERSION_1_0) 
    

    就像Eric Caron 说的那样。

    【讨论】:

      【解决方案8】:

      当我的服务器磁盘空间不足并在生成响应期间中途关闭连接并简单地关闭连接时,我收到此错误

      【讨论】:

        【解决方案9】:

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

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

        错误仍然存​​在,但我可以处理变量中的响应数据。

        【讨论】:

          【解决方案10】:

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

          我想当您阅读本文时,它不会真正“帮助”您,因为这意味着您的文件已被丢弃。

          【讨论】:

            【解决方案11】:

            我遇到了同样的问题。我尝试了所有这些解决方案,但都没有奏效。就我而言,该请求在 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 编码,我会返回错误。

            【讨论】:

              【解决方案12】:

              我在通过 nginx 代理运行时遇到此错误,并且我在用户 ID daemon 而不是用户 ID nginx 下运行 nginx

              这意味着一些 nginx 的临时目录不可访问/不可写。

              user daemon; 切换到user nginx; 为我解决了这个问题。

              【讨论】:

                【解决方案13】:

                它可能与许多问题有关。就我而言,我使用 Curl 构建图像(通过 Docker api)。因此,构建被卡住了,这就是我收到此错误的原因。 当我修复构建时,错误消失了。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-04-21
                  • 2021-04-09
                  • 2020-07-07
                  • 2019-09-13
                  • 1970-01-01
                  • 2021-01-03
                  • 2016-12-01
                  相关资源
                  最近更新 更多