PHP cURL发送Raw JSON体POST返回HTTP 0及DNS解析错误排查
异常根因拆解
首先明确一个基础逻辑:只要cURL在域名解析、TCP建连、TLS握手的前置阶段就失败,根本没拿到目标服务端返回的HTTP响应报文,curl_getinfo获取到的HTTP状态码就会返回0,这个结果本身不代表请求逻辑写错了,只是连接流程没走通而已。结合你补充的测试场景,具体异常原因分两类:
- Postman与PHP运行环境的DNS解析链路完全不一致
你测试替换URL为google.com时能正常收到405状态码,已经证明PHP cURL本身的网络能力、请求逻辑没有问题,差异完全出在域名解析环节。
Postman请求时的解析路径通常有几种:走系统代理的内置DNS、用自身内置的DoH加密DNS、读取本地hosts文件的固定映射。但PHP脚本运行时的解析路径是完全独立的:如果是本地跑的PHP脚本,会直接走当前操作系统的默认DNS配置;如果是部署在服务器/容器里的PHP环境,会走容器/操作系统配置的公共DNS。两边解析路径不一样,就会出现Postman能正常解析hello.net、拿到预期的400响应,但PHP环境对应的DNS服务器查询hello.net时直接返回无记录的情况,对应报错就是Could not resolve: hello.net (DNS server returned answer with no data)。 - 目标域名的DNS配置做了来源访问限制
hello.net的DNS服务可能配置了来源策略:仅对特定地区、特定出口IP、特定DNS服务商的查询请求返回解析结果,对PHP运行环境所属的DNS来源直接返回空响应。而Postman的实际请求出口(比如走了代理的节点、本地运营商出口)刚好在域名的可解析白名单里,所以能正常完成请求流程。
可落地的排查验证方法
- 在PHP运行的同一环境下,执行
nslookup hello.net、dig hello.net命令,确认是否和cURL报错一致,拿不到域名的IP解析结果。 - 核对Postman的网络配置:如果Postman开启了系统/手动代理,就给PHP cURL加上对应的代理配置
curl_setopt($ch, CURLOPT_PROXY, '代理地址:端口'),再重试请求看是否能正常解析。 - 检查是否存在hosts映射:如果Postman里是把hello.net绑定到了特定测试IP,就需要在PHP运行环境的hosts文件里加上同样的IP映射,否则PHP环境会按公网DNS规则查找域名,自然解析不到对应记录。
内容的提问来源于stack exchange,提问作者user1163234
相关产品推荐
相关产品推荐

