You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    }
}

关键注意点

  1. 前端必须阻止默认提交:如果不写e.preventDefault(),表单会直接刷新提交,Ajax逻辑根本不会生效。
  2. 后端要判断Ajax请求:通过$request->ajax()区分普通请求和Ajax请求,返回对应的响应格式。
  3. 错误响应要带状态码:返回422状态码,这样前端的Ajax会进入error回调,方便处理错误提示。
  4. 成功后前端跳转:Ajax请求下后端的重定向不会生效,需要前端通过window.location.href手动跳转。

这样修改后,登录错误时会在登录页对应的输入框下方显示错误信息,登录成功则直接跳转到目标页面,不会再出现空白页面输出JSON的情况了。

内容的提问来源于stack exchange,提问作者신형준

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:20:38