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

Bootstrap+jQuery多步骤支付表单路由/控制器异常,页面因闲置过期

Fixing "The page has expired due to inactivity" in Your Multi-Step Payment Form

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 @csrf directive 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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:46:31