header() 重定向失败是因为响应头已发送:PHP 要求 header() 必须在任何输出(含空格、BOM、换行、echo 等)前调用;常见原因有 UTF-8 BOM、文件末尾空白、调试代码残留等。

header() 重定向失败:页面已输出内容
PHP 的 header() 必须在任何实际输出(包括空格、换行、HTML、echo)之前调用,否则会报 Warning: Cannot modify header information - headers already sent。这不是 bug,是 HTTP 协议限制——响应头必须在响应体之前发送。
常见踩坑点:
- 文件开头有 UTF-8 BOM(尤其 Windows 编辑器保存时默认带 BOM),看似空白,实则已输出三个字节
-
require或include的文件末尾有多余换行或空格 - 调试时加了
var_dump()或print_r()又没删干净 - PHP 标签后紧跟换行,比如
?>\n<?php中的换行也算输出
验证方法:打开文件用十六进制编辑器查 BOM;或临时加 ob_start() 在入口第一行(仅临时排查,非解决方案)。
header() 重定向不生效:缺少 Location 和 exit
header() 只负责发响应头,不终止脚本执行。如果后续还有 HTML 输出或逻辑,浏览器可能忽略重定向,或先显示旧页面再跳转(极不可靠)。
立即学习“PHP免费学习笔记(深入)”;
正确写法必须成对出现:
header('Location: /login.php');
exit;注意:
- 路径用绝对路径更稳妥(如
/dashboard.php),相对路径(如dashboard.php)依赖当前请求 URI,容易出错 -
exit或die二选一即可,但不能省略;用return不行(只退出当前作用域) - HTTP 状态码建议显式指定,例如
header('Location: /404.php', true, 302),避免某些老旧代理误判
HTTPS 环境下 header() 跳转到 HTTP 链接被浏览器拦截
现代浏览器(Chrome/Firefox/Safari)会阻止从 HTTPS 页面发起的明文 HTTP 重定向,控制台报 Mixed Content 错误,跳转直接静默失败。
解决办法只有两个:
- 确保目标 URL 也是 HTTPS,比如把
http://example.com改成https://example.com - 如果目标域名不支持 HTTPS,只能改用前端跳转(
header()不适用),例如输出 JS:<script>location.href="http://...";</script>(但 SEO 和无 JS 场景不友好)
检查方式:用 curl -I 查看响应头中 Location 的值是否协议一致。
header() 重定向后 $_POST 数据丢失?不是 header 的问题
header('Location: ...') 是 302 临时跳转,浏览器会自动用 GET 方法访问新地址,所以原始 POST 请求体不会被携带过去——这是 HTTP 规范行为,和 PHP 无关。
需要保留数据时,只能手动处理:
- 用 session 暂存:跳转前
$_SESSION['post_data'] = $_POST;,目标页读取后及时 unset - 拼接查询参数(仅限少量、非敏感数据):
header('Location: /result.php?name=' . urlencode($_POST['name'])); - 改用 307 或 308 状态码(但兼容性差):
header('Location: /target.php', true, 307);,只有较新浏览器支持,且仍需服务端配合接收 POST
别指望 header() 自动转发 POST —— 它做不到,也不该做到。
最易被忽略的是:重定向不是“继续执行流程”,而是告诉浏览器“去另一个地址重新开始一次请求”。所有上下文都得自己重建,PHP 不会帮你传变量、不保存状态、不记住你刚提交了什么。











