php页面跳转不能只靠header(),必须配合exit、检查输出状态,并在失效时回退到js或meta方案;常见错误是“headers already sent”,因空格、bom或提前输出导致,需用headers_sent()定位,且跳转后务必exit防止后续代码执行。

PHP 页面跳转不能只靠 header(),很多场景下它会失效或引发警告,必须配合 exit、检查输出状态,甚至 fallback 到 JavaScript 或 meta 方案。
为什么 header("Location: ...") 会报“headers already sent”?
这是最常见也最容易被忽视的问题:PHP 在发送 HTTP 响应头前,任何实际输出(包括空格、BOM、echo、print、甚至文件末尾的换行)都会触发响应体开始,导致 header() 失败。
- 检查 PHP 文件是否以 UTF-8 无 BOM 格式保存(尤其 Windows 编辑器容易插入 BOM)
- 确认跳转前没调用过
echo、var_dump、print_r,哪怕在include的配置文件里也不行 - 使用
headers_sent($file, $line)快速定位哪行提前输出:if (headers_sent($file, $line)) { die("Headers already sent in $file on line $line"); }
安全跳转必须加 exit 或 die
header("Location: ...") 只是发响应头,PHP 会继续执行后续代码——这可能导致权限绕过、重复写库、敏感信息泄露等严重问题。
- 永远在
header()后紧跟exit(或die),二者缺一不可header("Location: /dashboard.php"); exit; - 不要写成
header("Location: ..."); return;——return对脚本全局执行无效 - 若跳转逻辑在函数内,
exit仍需显式写出,不能依赖函数返回
当 header() 不可用时,用 JS 或 meta 回退
比如已在 HTML 输出后才发现要跳转(如表单校验失败后想重定向),只能用客户端方案。注意:这不是“更好”的方式,而是不得已的 fallback。
立即学习“PHP免费学习笔记(深入)”;
- 优先用
script(兼容性好、立即执行):echo '<script>window.location.href="/login.php";</script>'; exit;
- 或用
meta(SEO 友好但有延迟):echo '<meta http-equiv="refresh" content="0;url=/login.php">'; exit;
- 切勿省略
exit—— 否则页面可能部分渲染后再跳,造成视觉混乱或逻辑冲突
带参数跳转要注意 URL 编码和安全性
拼接跳转 URL 时,用户输入的值(如 $_GET['from'])必须过滤,否则易引发开放重定向漏洞(Open Redirect)。
- 用
urlencode()编码参数值,不用rawurlencode()(除非明确需要斜杠不编码)$url = '/process.php?msg=' . urlencode($message);
- 白名单校验跳转目标:
$allowed_hosts = ['example.com', 'api.example.com']; $host = parse_url($_GET['redirect'], PHP_URL_HOST); if (!in_array($host, $allowed_hosts)) { $redirect = '/home.php'; } - 避免直接 echo 用户可控的跳转地址,哪怕用了
header()
真正难的不是写跳转代码,而是判断「此刻能否用 header()」——它取决于整个请求生命周期中有没有任何输出。很多线上 bug 都卡在这一步,而不是语法写错。











