使用CURL请求API返回1020错误,Postman却正常响应的原因排查
解决PHP CURL请求API返回1020错误(Postman请求正常)
1020错误是Cloudflare防火墙的拦截提示,说明你的CURL请求被识别为异常流量,和Postman的请求特征存在差异。以下是具体排查和修复步骤:
核心问题排查与修复
1. 修正请求头中的错误配置
- Host头错误:你代码里硬编码了
Host: localhost,这完全不符合目标API的实际域名,直接替换为Postman中显示的真实Host(比如api.example.com)。 - Cookie有效性问题:手动硬编码的
PHPSESSID和csrf_token可能已过期,或者与CURL运行环境的IP、UA不匹配(会话通常和客户端特征绑定)。建议移除手动Cookie,改用CURL自动处理会话:
添加CURLOPT_COOKIEJAR => 'cookie.txt'和CURLOPT_COOKIEFILE => 'cookie.txt',让CURL自动保存、加载Cookie,模拟Postman的会话流程。
2. 完全复刻Postman的请求参数
在Postman中点击「Code」按钮,选择「PHP - cURL」,直接复制生成的代码与你的代码对比:
- 检查是否遗漏了某些请求头(比如
Referer、Origin等); - 确保
User-Agent、Accept-Encoding等头与Postman完全一致; - 对于POST请求,要保证
CURLOPT_POSTFIELDS的内容格式、Content-Type头和Postman完全匹配。
3. 补充模拟正常请求的选项
添加以下CURL选项,让请求更接近Postman的行为:
CURLOPT_TCP_NODELAY => true, // 减少TCP延迟 CURLOPT_AUTOREFERER => true, // 自动设置跳转后的Referer
4. 排查环境差异
- 若CURL运行在服务器上,检查服务器IP是否被Cloudflare拉黑:可以在本地运行相同的CURL代码,看是否能成功,排除IP问题;
- 服务器是否有代理、防火墙修改了请求内容,导致特征异常。
修改后的示例代码
<?php $curl = curl_init(); // 替换为实际API地址 $apiUrl = 'your_actual_api_url_with_parameters'; curl_setopt_array($curl, array( CURLOPT_URL => $apiUrl, CURLOPT_RETURNTRANSFER => true, CURLOPT_ENCODING => 'gzip, deflate, br', CURLOPT_MAXREDIRS => 10, CURLOPT_TIMEOUT => 30, CURLOPT_FOLLOWLOCATION => true, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, CURLOPT_CUSTOMREQUEST => 'GET', // 自动处理Cookie CURLOPT_COOKIEJAR => 'cookie.txt', CURLOPT_COOKIEFILE => 'cookie.txt', CURLOPT_TCP_NODELAY => true, CURLOPT_AUTOREFERER => true, CURLOPT_HTTPHEADER => array( // 替换为API真实Host 'Host: actual-api-host.com', 'User-Agent: PostmanRuntime/7.31.0', 'Accept: */*', 'Accept-Encoding: gzip, deflate, br', 'Connection: keep-alive' ), )); $response = curl_exec($curl); // 输出错误信息方便排查 if(curl_errno($curl)) { echo 'CURL Error: ' . curl_error($curl); } curl_close($curl); echo $response; ?>
额外注意事项
- 生产环境不要禁用
CURLOPT_SSL_VERIFYPEER和CURLOPT_SSL_VERIFYHOST,仅在测试时临时使用; - 若API需要CSRF token,要先请求获取token的接口,再携带有效token发起请求,不要直接复用旧token。
内容的提问来源于stack exchange,提问作者Tech 4 Jazz
相关产品推荐
相关产品推荐

