DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

curl 发送 POST 时报 Could not resolve proxy: POST

curl 命令误写 -x POST 会把 POST 当成代理名。区分代理与请求方法参数,保留正常网络配置,并用表单上传示例核对修复后的请求。

上传文件或提交表单时,命令写成了 curl -x POST ...,随后出现:

curl: (5) Could not resolve proxy: POST

先看命令里的字母大小写。小写 -x 指定代理,后面的 POST 被当成代理主机名;大写 -X 才是指定 HTTP 请求方法。命令确实写了 -x POST 时,应先纠正这个参数,不必先改系统 DNS 或清空所有代理配置。

这个区别在旧版 curl 7.46 中已经存在,并非新版本才改变的语法。以下示例按 Bash、zsh 等 Shell 的换行方式书写;如果在其他终端执行,需使用该终端对应的续行方式,并确认调用的确实是 curl 程序。

报错里的 POST 是被误用的代理名

这段写法有误,只用于说明问题:

curl -x POST --form 'file=@sample.html' 'https://api.example.invalid/upload'

curl 读到 -x 后,会把紧接着的参数交给代理设置。它不会因为 POST 恰好也是 HTTP 方法名,就自动把小写选项解释成大写选项。于是,本应上传到接口的请求先卡在了代理名称解析上。

如果错误尾部显示的是一个真实的代理域名,而命令中没有把方法名传给 -x,那就是另一种情况:应核对代理地址、配置来源及名称解析。不能把所有 Could not resolve proxy 都归结为大小写笔误。

表单上传通常可以直接删掉 -x POST

HTTP 请求使用 --form(短选项 -F)时,curl 会构造 multipart 表单并采用 POST。仅为提交这样的表单,不需要再单独指定请求方法。

假设接口要求一个名为 file 的上传字段,当前目录已有用于测试的 sample.html,命令可以写成:

curl --form 'file=@sample.html;type=text/html' \
  'https://api.example.invalid/upload'

这里的地址是不可直接使用的占位地址。应替换成自己有权限调用的测试接口,并按接口要求替换字段名、文件与认证方式。文件应是可公开的测试内容,不能把生产文档或凭据当作排错样本上传。

@sample.html 表示把该文件作为上传部分;type=text/html 设置的是这个部分的媒体类型。整个 HTTP 请求仍由 curl 按 multipart 格式生成。它不是把文件内容作为原始 HTML 请求体发送,接口如果要求原始正文,就不能照搬这个表单示例。

若确实需要显式写出方法,可以使用更容易辨认的长选项:

curl --request POST \
  --form 'file=@sample.html;type=text/html' \
  'https://api.example.invalid/upload'

大写 -X POST 与这里的 --request POST 对应。两者只指定方法名,不会替你生成表单字段、补上认证或把某种正文转换成接口需要的格式。本例保留 --form,才有实际上传的数据。

确实需要代理时,把两个用途分别写清楚

网络要求通过代理访问接口时,代理地址仍要保留,只是不能把 POST 填进去。例如:

curl --proxy 'http://proxy.example.invalid:8080' \
  --form 'file=@sample.html;type=text/html' \
  'https://api.example.invalid/upload'

代理地址、端口和目标接口都是占位值,需使用获准的真实配置。这个命令仍会由 --form 选择 POST;代理地址和请求方法各自对应不同的选项。

也不要用 --noproxy 127.0.0.1 来修复这个笔误。--noproxy 指定的是哪些目标主机不经过代理,写入回环地址并不能让远端接口自动避开误设的 POST 代理。扩大到所有目标的绕过规则还会改变原本的网络访问路径。

只改错写的命令参数即可。修改脚本前保留原文件或版本控制记录,不要同时删除正常代理配置;否则,即使笔误修好了,也可能因为网络必须经过代理而出现新的连接失败。

验证到哪一层,结论就写到哪一层

替换好测试接口后,可以在上传命令末尾增加状态码输出:

curl --form 'file=@sample.html;type=text/html' \
  --write-out '\nHTTP %{http_code}\n' \
  'https://api.example.invalid/upload'

需要代理或认证的环境,应保留已经确认正确的相应选项。修复目标首先是让 curl 不再把 POST 当成代理去解析;随后再依据 HTTP 状态码、响应正文及测试服务的记录,确认请求方法、字段名和文件是否符合预期。

收到 400 或 415 等 HTTP 响应,不等于上传已经成功,应继续处理接口的字段或媒体类型要求;也不应因为出现了新的应用层错误,就把 -X 改回 -x。没有收到 HTTP 响应时,先看 curl 本身的错误信息,状态码输出不能替代传输错误判断。

表单提交可能创建记录、触发转换或保存文件。测试时使用可清理的测试对象,发生超时也先核对服务端是否已处理,再决定是否重试。恢复脚本只撤销本地修改,不能撤回已经发送的数据;测试产生的对象要按接口提供的方式清理。