laravel路由统一定义在routes/web.php或routes/api.php,由routeserviceprovider自动加载;重定向推荐route::redirect()用于静态跳转,动态场景需闭包+redirect()->route(),并手动处理查询参数透传。

路由定义写在哪、怎么注册
Laravel 的路由统一写在 routes/web.php(Web 请求)或 routes/api.php(API 请求),不是在控制器里,也不是在中间件里。新项目默认只加载这两个文件,靠 RouteServiceProvider 自动引入。
常见错误:把路由写在 app/Http/Controllers 里,或者试图在 config/ 下配路由——Laravel 不认。
- Web 路由会自动启用 Session、CSRF 等中间件;API 路由默认不带这些,别混用
- 如果要加自定义路由文件(比如
routes/admin.php),得手动在RouteServiceProvider::map()里require进来 -
php artisan route:list是唯一靠谱的验证方式,别光靠浏览器刷新猜有没有生效
重定向路由的三种写法及适用场景
Laravel 提供了 redirect()、RedirectController 和 Route::redirect() 三种主流方式,但它们触发时机和灵活性差别很大。
最常用也最轻量的是 Route::redirect():它不走控制器,直接返回 302 响应,适合静态跳转,比如旧 URL 迁移。
-
Route::redirect('/old', '/new', 301);—— 简单、无开销,但不能动态拼接参数 -
Route::get('/old', function () { return redirect('/new')->with('message', 'Moved'); });—— 可加 session、判断逻辑,但多一次函数调用 - 用
RedirectController@__invoke是 Laravel 9+ 新增的“无控制器”写法,本质还是走redirect(),但支持命名路由:Route::redirect('/old', '/new')->name('old.route');
注意:301 和 302 都能用,但搜索引擎只缓存 301,改错后很难撤回;开发期建议先用 302。
带参数的重定向容易漏掉的点
从 /user/{id} 跳到 /profile/{id} 看似简单,但 Route::redirect() 不解析占位符,它只做字符串替换,所以不能直接写 Route::redirect('/user/{id}', '/profile/{id}') —— 这样访问 /user/123 会跳去 /profile/{id},不是 /profile/123。
- 必须用闭包 +
redirect()->route()或redirect()->to()手动取参:Route::get('/user/{id}', fn ($id) => redirect("/profile/{$id}")); - 如果目标是命名路由,优先用
redirect()->route('profile.show', ['id' => $id]),避免硬编码路径 - 参数名不一致时(比如源路由是
{user_id},目标需要{id}),闭包里得显式映射,Laravel 不自动转换
重定向后丢失查询参数怎么办
默认所有重定向都不携带原始 URL 的 query string,比如访问 /search?q=laravel&sort=date,用 Route::redirect('/search', '/results') 会跳成 /results,q 和 sort 全丢。
没有内置开关一键保留,必须手动处理:
- 用闭包捕获
Request:Route::get('/search', function (Illuminate\Http\Request $request) { return redirect('/results?' . $request->getQueryString()); }); - 更安全的做法是用
$request->fullUrlWithQuery([]),它会过滤掉空值,避免生成?q=&sort=date这种脏参数 - 别在中间件里统一加 query 重定向——不同路由对 query 的依赖程度不同,硬塞可能破坏业务逻辑
重定向看着简单,但 query 透传、参数映射、状态码选择这三块,实际项目里八成问题都出在这儿,别图省事跳过验证。










