
php 使用 curl 发送 post 请求时,若目标 url 发生 http 重定向(如 301/302),默认情况下 post 数据会被丢弃;需显式启用 `curlopt_postredir` 选项才能在重定向后保留 post 方法和参数。
在 PHP 中通过 cURL 发起 POST 请求时,一个常见但容易被忽视的问题是:重定向导致 POST 数据丢失。你的 file1.php 在本地正常运行,但在服务器上 $_POST 为空,根本原因并非服务器配置差异(如 post_max_size 或 mod_security),而是服务端对目标 URL(如 /file2.php)存在隐式重定向(例如强制跳转到带尾部斜杠的路径 /file2.php/、HTTP → HTTPS 跳转,或域名规范化重定向)。
cURL 默认行为是:遇到 3xx 重定向响应时,自动将后续请求降级为 GET 方法,并清空 CURLOPT_POSTFIELDS —— 这正是 $_POST 在 file2.php 中为空的原因。
✅ 正确做法是启用 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_HTTPHEADER, ['Content-Type: application/x-www-form-urlencoded']);
// ? 关键修复:允许在所有重定向类型中保持 POST 方法
curl_setopt($curl, CURLOPT_POSTREDIR, CURL_REDIR_POST_ALL);
// 建议添加错误处理与返回值捕获
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; // 输出 file2.php 的响应? CURL_REDIR_POST_ALL 是 PHP 5.5.0+ 引入的常量,表示:无论重定向状态码是 301、302、303、307 还是 308,均保留原始 POST 方法及请求体。
⚠️ 注意事项:
- 若使用较老 PHP 版本(
- CURLOPT_FOLLOWLOCATION 必须启用,否则 CURLOPT_POSTREDIR 不生效;
- 避免同时设置 CURLOPT_CUSTOMREQUEST(如 'POST'),它会覆盖 CURLOPT_POST 行为;
- 生产环境建议始终启用 CURLOPT_RETURNTRANSFER 并检查 curl_exec() 返回值,便于调试。
总结:本地与服务器行为不一致,往往源于服务器配置引发的透明重定向。解决 POST 参数丢失问题,核心不是修改 Content-Type 或调整 http_build_query,而是正确配置重定向语义——CURLOPT_POSTREDIR 是 cURL 处理跨重定向 POST 的标准且可靠方案。
立即学习“PHP免费学习笔记(深入)”;











