如何在Laravel 5中实现登录表单的内联错误反馈
在Laravel 5中实现表单提交后对应字段旁显示错误消息
嘿,我来帮你搞定这个需求,要实现点击「submitBtn」后在对应输入字段旁显示错误消息,咱们分后端验证逻辑和前端视图修改两部分来弄,还可以加个无刷新的AJAX方案供你选择:
一、后端验证逻辑(Laravel端)
首先得让后端返回对应字段的错误信息,这里有两种常用方式:
方式1:使用表单请求验证(推荐,代码更整洁)
- 先创建一个登录请求类,用来统一管理验证规则:
php artisan make:request LoginRequest
- 打开
app/Http/Requests/LoginRequest.php,设置验证规则和自定义错误消息:
<?php namespace App\Http\Requests; use Illuminate\Foundation\Http\FormRequest; class LoginRequest extends FormRequest { // 允许所有用户访问这个请求 public function authorize() { return true; } // 定义验证规则 public function rules() { return [ 'username' => 'required|string', 'password' => 'required|string', ]; } // 可选:自定义更友好的错误消息 public function messages() { return [ 'username.required' => '用户名不能为空哦', 'password.required' => '密码可不能忘填呀', ]; } }
- 在处理登录的控制器(比如
LoginController)里,用这个请求类来验证:
use App\Http\Requests\LoginRequest; use Illuminate\Support\Facades\Auth; public function login(LoginRequest $request) { // 获取用户名和密码 $credentials = $request->only('username', 'password'); // 尝试登录 if (Auth::attempt($credentials)) { // 登录成功,跳转到首页(或者用户之前访问的页面) return redirect()->intended('/'); } // 用户名密码错误,返回表单页并携带错误信息 return back()->withErrors([ 'username' => '用户名或密码有误,请重新输入', ])->withInput(); // 保留用户之前输入的内容 }
方式2:直接在控制器里验证(快速实现)
如果不想单独创建请求类,也可以直接在控制器里写验证逻辑:
use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; public function login(Request $request) { // 直接验证请求参数 $this->validate($request, [ 'username' => 'required|string', 'password' => 'required|string', ], [ 'username.required' => '用户名不能为空', 'password.required' => '密码不能为空', ]); // 登录逻辑和上面一样 $credentials = $request->only('username', 'password'); if (Auth::attempt($credentials)) { return redirect()->intended('/'); } return back()->withErrors([ 'username' => '用户名或密码错误', ])->withInput(); }
二、前端视图修改(显示对应字段的错误)
现在修改你的前端代码,给每个输入框旁边加上错误提示的位置,利用Laravel自带的$errors变量来动态显示错误:
<!doctype html> <html lang="{{ str_replace('_', '-', app()->getLocale()) }}"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link href="/css/bootstrap.css" rel="stylesheet"> <link href="/css/bootstrap.min.css" rel="stylesheet"> <link href="/css/bootstrap-theme.css" rel="stylesheet"> <link href="/css/all.css" rel="stylesheet"> <link href="/css/all.min.css" rel="stylesheet"> <link href="/css/Style.css" rel="stylesheet"> <script src="/js/jquery-2.2.4.min.js"></script> <script src="/js/bootstrap.js"></script> <script src="/js/all.js"></script> <script src="/js/all.min.js"></script> <title>LOGIN</title> <!-- Fonts --> <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet"> </head> <body> <form id="form1" action="/loginme" method="post"> <div> <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="login_form"> <div class="inputWithIcon"> <i class="fas fa-user-tie"></i> <!-- 验证失败时给输入框加错误样式 --> <input type="text" placeholder="Username" class="form-control {{ $errors->has('username') ? 'is-invalid' : '' }}" name="username" value="{{ old('username') }}" <!-- 保留之前输入的内容 --> /> <!-- 用户名的错误提示 --> @if($errors->has('username')) <div class="invalid-feedback"> {{ $errors->first('username') }} </div> @endif </div> <div class="inputWithIcon"> <i class="fas fa-unlock-alt"></i> <input type="password" placeholder="Password" class="form-control {{ $errors->has('password') ? 'is-invalid' : '' }}" name="password" /> <!-- 密码的错误提示 --> @if($errors->has('password')) <div class="invalid-feedback"> {{ $errors->first('password') }} </div> @endif </div> <br /> <input type="submit" id="submitBtn" class="btn btn-secondary btn-block login-submit-btn" value="Login"> </div> </div> </form> </body> </html>
这里的关键修改点:
- 给输入框添加了
{{ $errors->has('字段名') ? 'is-invalid' : '' }},验证失败时输入框会变成Bootstrap的红色错误样式 - 在每个输入框下方添加了错误提示容器,用
@if($errors->has('字段名'))判断是否显示错误,$errors->first('字段名')取第一条错误消息 - 用户名输入框加了
value="{{ old('username') }}",验证失败时保留用户输入的内容,不用重新填写
三、可选:无刷新AJAX提交(页面不跳转就显示错误)
如果想要更流畅的体验,不想页面刷新,那就用AJAX提交表单,动态显示错误:
前端添加AJAX代码
在</body>标签之前加入这段JS代码:
<script> $(document).ready(function() { $('#form1').submit(function(e) { e.preventDefault(); // 阻止默认的表单提交跳转 // 先清除之前的错误提示和样式 $('.form-control').removeClass('is-invalid'); $('.invalid-feedback').remove(); // 发送AJAX请求 $.ajax({ url: $(this).attr('action'), method: 'POST', data: $(this).serialize(), // 序列化表单数据 success: function() { // 登录成功,跳转到首页 window.location.href = '/'; }, error: function(xhr) { if (xhr.status === 422) { // Laravel验证失败返回422状态码 let errors = xhr.responseJSON.errors; // 遍历错误,添加到对应字段旁边 $.each(errors, function(field, messages) { let input = $('input[name="' + field + '"]'); input.addClass('is-invalid'); input.after('<div class="invalid-feedback">' + messages[0] + '</div>'); }); } else if (xhr.status === 401) { // 用户名密码错误 $('input[name="username"]').addClass('is-invalid'); $('input[name="username"]').after('<div class="invalid-feedback">用户名或密码错误</div>'); } } }); }); }); </script>
后端修改返回JSON响应
在LoginController的login方法里,判断是否是AJAX请求,返回JSON格式的错误:
use Illuminate\Http\JsonResponse; public function login(LoginRequest $request) { $credentials = $request->only('username', 'password'); if (Auth::attempt($credentials)) { if ($request->wantsJson()) { return response()->json(['success' => true], 200); } return redirect()->intended('/'); } // 登录失败,AJAX请求返回JSON错误 if ($request->wantsJson()) { return response()->json([ 'errors' => [ 'username' => ['用户名或密码错误'] ] ], 401); } // 普通请求返回页面错误 return back()->withErrors([ 'username' => '用户名或密码错误', ])->withInput(); }
这样不管是普通表单提交还是AJAX提交,都能正常显示对应的错误消息啦!
内容的提问来源于stack exchange,提问作者ahmedshpt
相关产品推荐
相关产品推荐

