Laravel中如何通过Ajax实现点击验证模态登录表单
Got it, let's fix that frustrating modal login experience right away. The issue is that your current form does a full page refresh, which closes the modal and forces users to re-open it to see errors. Let's switch to Ajax submission so everything happens without reloading the page. Here's a step-by-step solution tailored to your code:
Step 1: Update the Form HTML
First, we'll tweak the form to make it Ajax-friendly, fix duplicate attributes, and add containers for dynamic error messages (since Blade's @error only works on server-rendered pages):
<form id="loginForm"> @csrf <div class="sign-in-wrapper"> <a href="#0" class="social_bt facebook">Login with Facebook</a> <a href="#0" class="social_bt google">Login with Google</a> <div class="divider"><span>Or</span></div> <div class="form-group"> <label>Email</label> <input type="email" name="email" class="form-control" id="email"> <i class="icon_mail_alt"></i> <!-- Dynamic error container --> <div class="error-message" style="color: red;"></div> </div> <div class="form-group"> <label>Password</label> <input type="password" name="password" class="form-control" id="password"> <i class="icon_lock_alt"></i> <!-- Dynamic error container --> <div class="error-message" style="color: red;"></div> </div> <div class="clearfix add_bottom_15"> <div class="checkboxes float-left"> <input id="remember-me" type="checkbox" name="remember"> <label for="remember-me">Remember Me</label> </div> <div class="float-right"><a id="forgot" href="javascript:void(0);">Forgot Password?</a></div> </div> <div class="text-center"> <button type="submit" class="btn_login">Log In</button> </div> <div class="text-center"> Don’t have an account? <a href="{{ url('/register') }}">Sign up</a> </div> <div id="forgot_pw"> <div class="form-group"> <label>Please confirm login email below</label> <input type="email" class="form-control" name="email_forgot" id="email_forgot"> <i class="icon_mail_alt"></i> </div> <p>You will receive an email containing a link allowing you to reset your password to a new preferred one.</p> <div class="text-center"><input type="submit" value="Reset Password" class="btn_1"></div> </div> </div> </form>
Note: I removed duplicate name attributes on inputs and renamed the "remember me" checkbox to remember (matches Laravel's default auth logic).
Step 2: Add Ajax Handling with JavaScript
Add this script at the bottom of your page (or in a dedicated JS file) to handle form submission without a refresh. We'll use jQuery since Laravel includes it by default:
$(document).ready(function() { $('#loginForm').on('submit', function(e) { // Stop the form from doing a full page submit e.preventDefault(); // Clear any previous error messages $('.error-message').text(''); // Collect form data (including CSRF token) const formData = $(this).serialize(); // Send Ajax request to login endpoint $.ajax({ url: '/login', type: 'POST', data: formData, success: function() { // On successful login, redirect to your dashboard/homepage window.location.href = '/'; }, error: function(xhr) { // Handle validation errors (Laravel returns 422 status for failed validation) if (xhr.status === 422) { const errors = xhr.responseJSON.errors; // Loop through errors and display them under the corresponding field $.each(errors, function(field, messages) { $(`#${field}`).next('.error-message').text(messages[0]); }); } else { // Handle other errors (e.g., server issues) alert('Something went wrong. Please try again later.'); } } }); }); });
Step 3: Update the Login Controller
We need to modify Laravel's default login logic to return JSON responses instead of redirects when handling Ajax requests. Open app/Http/Controllers/Auth/LoginController.php and override the login method:
use Illuminate\Http\Request; class LoginController extends Controller { // Keep all existing default code here... public function login(Request $request) { $this->validateLogin($request); // Handle login throttling (default Laravel behavior) if (method_exists($this, 'hasTooManyLoginAttempts') && $this->hasTooManyLoginAttempts($request)) { $this->fireLockoutEvent($request); return $this->sendLockoutResponse($request); } // If login is successful if ($this->attemptLogin($request)) { if ($request->hasSession()) { $request->session()->put('auth.password_confirmed_at', time()); } // Return JSON for Ajax requests, else default redirect if ($request->ajax()) { return response()->json(['success' => true]); } return $this->sendLoginResponse($request); } // Increment login attempts on failure $this->incrementLoginAttempts($request); // Return JSON error for Ajax requests, else default error response if ($request->ajax()) { return response()->json([ 'errors' => [ 'email' => [trans('auth.failed')] ] ], 422); } return $this->sendFailedLoginResponse($request); } }
Step 4: Test It Out
Now when users submit invalid credentials:
- The modal stays open
- Error messages appear directly under the relevant fields
- No page refresh happens
For valid credentials, users will be redirected to your homepage/dashboard as usual.
内容的提问来源于stack exchange,提问作者FuadFarhadoghlu

