ThinkPHP 6 的 domain 路由绑定不支持直接 301 重定向,因其仅负责域名请求分发,不发送 HTTP 状态码;强制跳转需在全局中间件中通过 response()->redirect() 实现响应级中断,并根据 $_SERVER['HTTP_HOST'] 安全判断与协议动态拼接目标 URL。

ThinkPHP 6 的 domain 路由绑定不支持直接 301 重定向
域名重定向不是路由绑定的本职工作,domain 只负责把某个域名下的请求分发到指定分组或控制器,它本身不会发 HTTP 状态码。想实现 www.example.com → example.com 这类强制跳转,得在路由定义之外加一层判断。
常见错误是写成这样:
Route::domain('www.example.com', function () {
Route::redirect('/', 'https://example.com/', 301);
});
这看似合理,但实际会触发无限重定向——因为 redirect 是内部跳转,不改变浏览器地址栏,且未切断原始请求流程。真正生效的必须是响应级中断。
- 正确做法:在全局中间件或
app/middleware.php中拦截www域名请求 - 用
response()->redirect()发起真实 HTTP 重定向,并立即return - 注意检查
$_SERVER['HTTP_HOST'],别只依赖request()->host()(可能被伪造)
如何在中间件里安全做域名跳转
中间件是最可控的位置,既早于路由解析,又能访问完整请求上下文。关键点在于:必须提前返回响应,否则后续逻辑还会执行。
立即学习“PHP免费学习笔记(深入)”;
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
示例中间件(app/middleware/DomainRedirect.php):
public function handle($request, \Closure $next)
{
$host = $request->header('host', '');
if (strpos($host, 'www.') === 0) {
$target = 'https://' . ltrim($host, 'www.');
return response()->redirect($target, 301);
}
return $next($request);
}
- 用
$request->header('host')比request()->domain()更可靠,后者可能已被路由层修改 - 硬编码
https://不稳妥,应根据$request->isSsl()动态拼协议 - 别忘了在
app/middleware.php中注册该中间件为全局(http类型),否则只对某些路由生效
使用 Route::domain 时容易忽略的协议和端口问题
Route::domain() 匹配的是 Host 头,不关心协议、端口、路径。这意味着 http://example.com:8080 和 https://example.com 都能命中同一规则——但它们很可能需要不同处理逻辑。
- 开发环境常跑在非标准端口(如
:8000),上线后却忘了删掉端口匹配逻辑,导致生产环境路由失效 - 如果用了反向代理(Nginx / Apache),
Host头可能被改写,需确认fastcgi_param HTTP_HOST $host;是否正确传递 -
Route::domain('example.com')不会匹配带端口的请求,除非显式写成'example.com:8000'(不推荐)
为什么不用 Nginx/Apache 做重定向更简单
应用层做域名跳转,本质是让 PHP 承担了 Web 服务器本该干的活。尤其在高并发下,每次请求都要进框架生命周期,白白消耗资源。
Nginx 示例配置(比中间件快一个数量级):
server {
listen 80;
server_name www.example.com;
return 301 https://example.com$request_uri;
}
- Web 服务器在建立连接后立刻响应,不走 PHP-FPM,毫秒级完成
- 避免因框架异常(如数据库挂了、缓存崩了)导致重定向也失败
- 唯一限制:无法做动态逻辑(比如“仅对登录用户跳转”),这种才必须放 PHP 层
多数场景下,域名规范跳转就该交给 Nginx;只有当跳转逻辑依赖用户状态、数据库字段或业务规则时,才值得动用中间件。


















