Bootstrap+jQuery多步骤支付表单路由/控制器异常,页面因闲置过期
Hey there! That "page expired" error is super common when building multi-step flows in Laravel, especially with Bootstrap/jQuery forms. Let’s break down what’s going on and how to fix it:
Why This Happens
That error is Laravel’s CSRF protection kicking in — it’s designed to block unauthorized requests. Chances are one of these is happening:
- Your form submissions aren’t including the required CSRF token
- You’re using GET requests for steps that should be POST (since GET doesn’t trigger CSRF checks, but it’s unsafe for submitting user/payment data)
- Session data from previous steps is getting lost, causing the flow to break
Step-by-Step Fixes
1. Make Sure Every Submission Includes the CSRF Token
Laravel requires all POST requests to have a valid CSRF token. Here’s how to handle this:
- For regular form submits: Add the
@csrfdirective directly inside each step’s form:<form id="step1-form" action="{{ route('payment.step1') }}" method="POST"> @csrf <div class="form-group"> <label for="name">Name</label> <input type="text" name="name" id="name" class="form-control" required> </div> <div class="form-group"> <label for="email">Email</label> <input type="email" name="email" id="email" class="form-control" required> </div> <button type="submit" class="btn btn-primary">Proceed to Step 2</button> </form> - For jQuery AJAX submits: Add a meta tag to your layout file, then configure jQuery to include the token in all AJAX headers:
<!-- In your main layout's <head> --> <meta name="csrf-token" content="{{ csrf_token() }}">// In your JS file or script tag $.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } }); // Example AJAX submit for Step 1 $('#step1-form').on('submit', function(e) { e.preventDefault(); $.post($(this).attr('action'), $(this).serialize(), function(response) { // Swap out the step content with Step 2's HTML $('#multi-step-container').html(response); }); });
2. Store Step Data in the Session
Since you’re splitting the form into separate controller methods, you need to persist data between steps. Use Laravel’s session to store user input as they progress:
// PaymentController.php - Step 1 Method public function step1(Request $request) { // Validate the user's input $validated = $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|email', ]); // Store validated data in the session session()->put('payment.user_info', $validated); // Redirect to Step 2 (use GET for displaying the form, POST for submitting it) return redirect()->route('payment.step2'); } // PaymentController.php - Step 2 Display Method public function step2() { // Make sure the user completed Step 1 first if (!session()->has('payment.user_info')) { return redirect()->route('payment.step1')->with('error', 'Please complete Step 1 first.'); } return view('payment.step2'); }
3. Fix Your Routes
Structure your routes so that displaying a step uses GET, and submitting step data uses POST (safe for sensitive info):
// routes/web.php use App\Http\Controllers\PaymentController; // Display Step 1 form Route::get('/payment/step1', [PaymentController::class, 'showStep1'])->name('payment.step1.show'); // Submit Step 1 data Route::post('/payment/step1', [PaymentController::class, 'step1'])->name('payment.step1'); // Display Step 2 form Route::get('/payment/step2', [PaymentController::class, 'step2'])->name('payment.step2'); // Submit Step 2 payment method selection Route::post('/payment/step2', [PaymentController::class, 'processStep2'])->name('payment.step2.process'); // Repeat for Steps 3 and 4
4. Handle Session Expiry Gracefully
If a user leaves the page open too long, their session might expire. Add checks in your controller methods to redirect back to the start with a friendly message:
public function step3() { if (!session()->has('payment.user_info') || !session()->has('payment.payment_method')) { return redirect()->route('payment.step1')->with('error', 'Your session has expired. Please start over.'); } return view('payment.step3'); }
Quick Check List
- All POST forms include
@csrf - AJAX requests include the CSRF token in headers
- Step data is stored in the session between controller methods
- Routes use GET for displaying forms, POST for submitting data
That should resolve the "page expired" error and get your multi-step payment form working smoothly!
内容的提问来源于stack exchange,提问作者user9659025

