Laravel搜索分页链接跳转404问题求助
分页点击下一页出现404错误(仅第一页正常)
问题现象
- 仅第一页搜索结果可正常加载,点击分页组件的下一页链接时,页面返回404 Not Found错误
- 错误请求链接示例:
http://127.0.0.1:8000/profile/search?page=2
相关代码
1. web.php路由配置
Route::post('/profile/search', [ProfilesController::class, 'search'])->name('profile.search');
2. ProfilesController的search方法
public function search() { $validated = request()->validate([ 'search_input' => 'string', 'search_by' => '', ]); if($validated['search_by'] === 'username') { $users = User::where('username', 'LIKE', '%'.$validated['search_input'].'%')->paginate(5); return view('profiles.search', compact('users')); } else { return redirect(route('profile.show', $validated['search_input'])); } }
3. profiles.search视图片段
@foreach ($users as $user) <tr> <td>{{ $user->id }}</td> <td><img class="rounded-circle" style="max-width: 80px" src="/storage/{{ $user->profile->profile_picture ?? 'defaults/placeholder_pfp.png' }}" alt="pfp"></td> <td> <a class="text-dark" href="{{ route('profile.show', $user->id) }}"> <b>{{ $user->username }}</b> </a> </td> </tr> @endforeach </table> {{ $users->links() }}
已尝试的解决方法
- 手动设置分页路径为路由路径
- 将POST方法改为GET
- 调整web.php中的路由顺序
- 为路由路径添加可选变量
- 查阅Stack Overflow相关讨论但未解决
问题根源
路由配置为POST方法,但Laravel分页组件生成的下一页链接默认是GET请求,点击时会以GET方式访问/profile/search,而该路由仅支持POST,因此返回404。即便尝试过改成GET,可能没同步处理表单提交方式或分页参数传递逻辑。
正确解决方案
1. 修改路由为GET请求
更新web.php中的路由,将POST改为GET:
Route::get('/profile/search', [ProfilesController::class, 'search'])->name('profile.search');
2. 同步前端表单提交方式
确保搜索表单使用GET方法提交,这样搜索参数会被拼接到URL中,分页链接才能继承这些参数:
<form action="{{ route('profile.search') }}" method="GET"> <input type="text" name="search_input" placeholder="输入用户名"> <select name="search_by"> <option value="username">按用户名搜索</option> </select> <button type="submit">搜索</button> </form>
3. 让分页链接携带搜索参数
默认分页链接不会带上搜索参数,点击下一页会丢失搜索条件,需修改视图中的分页代码:
{{ $users->appends(request()->query())->links() }}
appends(request()->query())会自动把当前URL中的所有查询参数(如search_input、search_by)添加到分页链接中,确保每一页的搜索结果一致。
4. 优化控制器SQL安全(可选)
原代码拼接LIKE条件存在SQL注入风险,建议改用参数绑定方式:
$users = User::where('username', 'LIKE', '%' . $validated['search_input'] . '%')->paginate(5); // 更安全的参数绑定写法: $users = User::where('username', 'LIKE', ?) ->setBindings(['%' . $validated['search_input'] . '%']) ->paginate(5);
5. 清除路由缓存(若修改路由后仍无效)
执行Artisan命令清除路由缓存,确保新路由生效:
php artisan route:clear
内容的提问来源于stack exchange,提问作者Nathan
相关产品推荐
相关产品推荐

