php 7.3 中 post 请求遇 302 非错误,而是重定向;默认不自动跳转,且 302 会将 post 降级为 get,需用 curl 设置 curlopt_followlocation、returntransfer 和 maxredirs 来自动获取最终响应。

PHP 7.3 中用 POST 请求遇到 302 响应,本质不是错误,而是服务器要求重定向。关键在于:**默认不自动跳转,且 POST 方法在跳转时可能被降级为 GET(除非用 307/308)**。处理方式取决于你的目标——是拿到最终响应内容,还是需要保留 POST 行为、审计跳转链,或手动控制每一步。
开启自动跳转并获取最终响应
这是最常用场景:你只关心最终返回的数据,不介意中间过程。需同时满足三个 cURL 选项:
- CURLOPT_FOLLOWLOCATION => true:启用跳转跟随
- CURLOPT_RETURNTRANSFER => true:确保 curl_exec() 返回字符串而非直接输出
- CURLOPT_MAXREDIRS => 5:设跳转上限,防环形跳转(open_basedir 启用时该选项必设)
示例代码:
$ch = curl_init('https://api.example.com/login');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, ['user' => 'a', 'pass' => 'b']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 5);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // 最终状态码,如 200
$finalUrl = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL); // 实际到达的 URL
curl_close($ch);
注意 POST 跳转后的方法变化
标准 HTTP 规范中,302 响应后的重定向默认使用 GET 方法(即使原始请求是 POST)。这意味着:
- 若跳转目标页依赖 POST 数据(如表单提交后跳转结果页),自动跟随可能丢失数据
- 服务器若返回的是 307 Temporary Redirect 或 308 Permanent Redirect,则会保留原始请求方法和 body,此时自动跟随是安全的
- 如果必须保持 POST 方法跳转,而服务器只返回 302,只能手动处理:先取 Location 头,再用新 URL 发起新 POST
手动处理跳转(保留 POST 或调试用)
适用于需要控制每次请求、检查中间状态、或避免方法降级的情况:
- 发起原始 POST 请求,但 禁用 FOLLOWLOCATION
- 检查响应头中的
Location字段(可用 curl_getinfo($ch, CURLINFO_REDIRECT_URL) 或 CURLOPT_HEADERFUNCTION 捕获) - 用新 URL 再次发起 POST 请求(可复用相同参数)
简版示例:
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true); // 获取响应头
curl_setopt($ch, CURLOPT_NOBODY, false);
$result = curl_exec($ch);
$headerSize = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
$headers = substr($result, 0, $headerSize);
$body = substr($result, $headerSize);
if (curl_getinfo($ch, CURLINFO_HTTP_CODE) == 302) {
if (preg_match('/Location:\s*(.+)/i', $headers, $matches)) {
$nextUrl = trim($matches[1]);
// 用 $nextUrl 再次 POST...
}
}
补充说明
file_get_contents 不推荐用于 POST + 302 场景:它虽支持 follow_location,但无法发送 POST 数据(除非用 method 和 content 手动构造),也不返回中间状态信息,调试困难。cURL 是更可靠的选择。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











