
当使用 php curl 发送 post 请求时,若目标 url 发生重定向(如 http → https 或路径跳转),默认情况下 curl 会将重定向后的请求转为 get,导致原始 post 数据丢失;启用 `curlopt_postredir` 可确保重定向后仍保留 post 方法和数据。
在开发中,我们常通过 cURL 实现服务间接口调用。如示例中 file1.php 向 file2.php 提交表单数据,本地环境正常而生产服务器返回空 $_POST,根本原因往往不是代码语法错误,而是HTTP 重定向行为差异所致。
cURL 默认对 301/302 重定向的处理策略是:仅对原始请求方法为 GET 或 HEAD 时自动跟随重定向;若原请求为 POST,则重定向后会改用 GET 方法发起新请求,并丢弃所有 POSTFIELDS。这意味着即使设置了 CURLOPT_FOLLOWLOCATION => true,POST 数据依然无法抵达最终目标。
✅ 正确做法是显式启用 CURLOPT_POSTREDIR 选项,告知 cURL 在重定向时保持 POST 方法并重新提交原始数据:
'John',
'age' => 24
]);
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $Url);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $PostFields);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL); // ? 关键修复项
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 推荐:捕获响应而非直接输出
$response = curl_exec($curl);
if ($response === false) {
error_log('cURL error: ' . curl_error($curl));
}
curl_close($curl);
echo $response;⚠️ 注意事项:
立即学习“PHP免费学习笔记(深入)”;
- CURL_REDIR_POST_ALL(值为 3)表示对所有重定向类型(301、302、303、307、308)均保留 POST;
- 若仅需支持 301/302,可使用 CURL_REDIR_POST_301 | CURL_REDIR_POST_302(值为 1|2=3),效果相同;
- 务必添加 CURLOPT_RETURNTRANSFER => true,避免响应直接输出干扰逻辑;
- 生产环境应检查服务器是否强制 HTTPS 重定向(如 Nginx/Apache 的 return 301 https://...),这正是触发该问题的常见场景;
- 不要依赖 CURLOPT_CUSTOMREQUEST 模拟 POST,它不自动设置 Content-Type 且无法正确传递 POSTFIELDS。
总结:本地与服务器表现不一致,本质是环境差异引发的重定向策略冲突。CURLOPT_POSTREDIR 是解决 cURL POST 在重定向中失效的标准方案,应在所有需跟随重定向的 POST 请求中默认启用。











