Laravel使用php artisan make:auth实现Ajax登录异常求助
解决Ajax登录后无法在登录页显示错误/跳转的问题
我来帮你一步步搞定这个问题,核心是要同时调整前端的表单提交逻辑和后端的响应格式,让Ajax请求能在当前登录页处理结果,而不是直接输出JSON内容。
第一步:修改前端登录页面(login.blade.php)
首先要阻止表单的默认刷新提交行为,改用Ajax异步请求,同时预留错误信息的显示位置:
<!-- 给表单添加ID方便JS选择 --> <form id="login-form" method="POST" action="{{ route('login') }}"> @csrf <div class="form-group"> <label for="email">邮箱</label> <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus> <!-- 用于显示邮箱字段的错误 --> <span class="invalid-feedback" role="alert"></span> </div> <div class="form-group"> <label for="password">密码</label> <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password"> <!-- 用于显示密码字段的错误 --> <span class="invalid-feedback" role="alert"></span> </div> <div class="form-group"> <div class="form-check"> <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}> <label class="form-check-label" for="remember"> {{ __('记住我') }} </label> </div> </div> <div class="form-group mb-0"> <button type="submit" class="btn btn-primary"> {{ __('登录') }} </button> </div> </form> <!-- 添加Ajax处理的JS代码(用jQuery示例,axios也可以类似调整) --> <script src="https://code.jquery.com/jquery-3.6.4.min.js"></script> <script> $(document).ready(function() { $('#login-form').on('submit', function(e) { // 阻止默认表单提交,避免页面刷新 e.preventDefault(); // 清空之前的错误提示 $('.invalid-feedback').text(''); $('.form-control').removeClass('is-invalid'); // 获取表单数据 const formData = $(this).serialize(); // 发送Ajax请求 $.ajax({ url: $(this).attr('action'), type: 'POST', data: formData, success: function(res) { // 登录成功,跳转到首页(替换成你需要的跳转地址) window.location.href = '/home'; }, error: function(xhr) { // 处理登录失败的错误信息 if (xhr.responseJSON?.error) { const errors = xhr.responseJSON.error; // 把错误信息显示到对应输入框下方 $.each(errors, (key, msg) => { $(`#${key}`).addClass('is-invalid'); $(`#${key}`).next('.invalid-feedback').text(msg); }); } } }); }); }); </script>
第二步:修改后端LoginController
找到app/Http/Controllers/Auth/LoginController.php,重写login方法,适配Ajax请求的响应格式:
<?php namespace App\Http\Controllers\Auth; use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; class LoginController extends Controller { use AuthenticatesUsers; /** * 登录后跳转地址 * * @var string */ protected $redirectTo = '/home'; /** * 创建控制器实例 * * @return void */ public function __construct() { $this->middleware('guest')->except('logout'); } /** * 重写登录方法,处理Ajax请求 */ public function login(Request $request) { // 验证登录参数 $this->validateLogin($request); // 处理登录次数限制 if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } // 尝试登录 if ($this->attemptLogin($request)) { // 如果是Ajax请求,返回成功JSON if ($request->ajax()) { return response()->json(['success' => true]); } return $this->sendLoginResponse($request); } // 登录失败,增加尝试次数 $this->incrementLoginAttempts($request); // 如果是Ajax请求,返回错误JSON(带422状态码触发前端error回调) if ($request->ajax()) { return response()->json([ 'error' => [ 'email' => 'This is invalid id.' // 这里用你自定义的错误信息 ] ], 422); } return $this->sendFailedLoginResponse($request); } }
关键注意点
- 前端必须阻止默认提交:如果不写
e.preventDefault(),表单会直接刷新提交,Ajax逻辑根本不会生效。 - 后端要判断Ajax请求:通过
$request->ajax()区分普通请求和Ajax请求,返回对应的响应格式。 - 错误响应要带状态码:返回422状态码,这样前端的Ajax会进入
error回调,方便处理错误提示。 - 成功后前端跳转:Ajax请求下后端的重定向不会生效,需要前端通过
window.location.href手动跳转。
这样修改后,登录错误时会在登录页对应的输入框下方显示错误信息,登录成功则直接跳转到目标页面,不会再出现空白页面输出JSON的情况了。
内容的提问来源于stack exchange,提问作者신형준
相关产品推荐
相关产品推荐

