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

Laravel 9中如何通过Ajax点击提交按钮向数据库POST数据?

问题修复方案

你的代码存在几个关键问题,导致Ajax请求无法正常工作,以下是逐一修复的步骤和修正后的代码:


1. 核心问题梳理

  • 缺少Laravel CSRF令牌,POST请求会被框架拦截
  • Ajax请求未携带表单数据,控制器无法获取提交的字段
  • JavaScript语法错误(Method大写、选择器未加引号)
  • 提交按钮为submit类型,触发表单默认跳转,中断Ajax流程
  • 控制器尝试获取表单中不存在的name和user_id字段,会抛出错误

2. 修正后的代码

Blade视图代码

Let us know a bit about Your running goals and experience so we can offer You the best training plan!

<!-- Button trigger modal -->
<button type="button" class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#exampleModal">
  Take a quick survey
</button>

<!-- Modal -->
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true">
    <div class="modal-dialog modal-dialog-centered modal-xl">
        <div class="modal-content">
            <div class="modal-header">
                <h1 class="modal-title fs-5" id="exampleModalLabel">Runner Survey</h1>
                <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
            </div>
            <div class="modal-body">
                <!-- 移除action="/",因为用Ajax提交 -->
                <form id="survey">
                    <!-- 添加Laravel CSRF令牌 -->
                    @csrf
                    <div class="row mb-3">
                        <label for="level" class="col-md-4 col-form-label text-md-end">I would describe my current level of fitness as</label>
                        <div class="col-md-6">
                            <!-- 移除form="survey",因为已经在表单内部 -->
                            <select name="level" id="level" class="form-control" required autocomplete="new-level">
                                <option value="beginner">Beginner</option>
                                <option value="intermediate">Intermediate</option>
                                <option value="advanced">Advanced</option>
                            </select>
                        </div>
                    </div>

                    <div class="row mb-3">
                        <label for="distance" class="col-md-4 col-form-label text-md-end">The distance I want to run in km is</label>
                        <div class="col-md-6">
                            <select name="distance" id="distance" class="form-control" required autocomplete="new-distance">
                                <option value="5">5</option>
                                <option value="10">10</option>
                            </select>
                        </div>
                    </div>

                    <div class="row mb-3">
                        <label for="time" class="col-md-4 col-form-label text-md-end">How many weeks do you have to achieve it?</label>
                        <div class="col-md-6">
                            <select name="time" id="time" class="form-control" required autocomplete="new-time">
                                <option value="4">4</option>
                                <option value="8">8</option>
                                <option value="12">12</option>
                            </select>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                        <!-- 把type改成button,避免默认表单提交;或者保留submit但在JS中阻止默认行为 -->
                        <button id="savebtn" type="button" class="btn btn-primary submit" onclick="saveForm('{{ route('forms.store')}}')">Save changes</button>
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<!-- Fin Modal -->

JavaScript函数

function saveForm(route){
    // 序列化表单数据,包含CSRF令牌和所有字段
    const formData = $('#survey').serialize();
    
    const request = $.ajax({
        // 修正为小写method
        method: 'POST',
        url: route,
        data: formData,
        // 指定响应类型为JSON
        dataType: 'json'
    }).done(function(response) {
        // 修正选择器引号
        $('#savebtn').text('Saved');
        // 关闭模态框
        $('#exampleModal').modal('hide');
        // 提示成功信息
        alert(response.message);
    }).fail(function(xhr) {
        // 处理错误
        alert('提交失败:' + xhr.responseJSON.message);
    });
}

Controller代码

use Illuminate\Support\Facades\Auth;

public function store(FormsRequest $request) 
{
    $data = $request->validated();

    // 注意:表单中没有name和user_id字段,这里做两种处理:
    // 1. 如果需要user_id,从登录用户获取(需确保用户已登录)
    $userId = Auth::id();
    // 2. 如果name是必填,需要在表单中添加对应的输入框,否则移除该行
    // $name = $data['name'];

    $level= $data['level'];
    $time=$data['time'];
    $distance=$data['distance'];

    $result = $this->formService->store($userId, $level, $time, $distance);
    // 返回JSON响应,方便JS处理
    return response()->json(['message' => 'Created successfully!']);
}

3. 额外说明

  • 如果你的FormsRequest验证规则中包含name和user_id,需要同步修改规则,或者在表单中添加对应的输入字段
  • 确保forms.store路由已在routes/web.php中正确定义:
    Route::post('/forms', [FormsController::class, 'store'])->name('forms.store');
    
  • 确保已引入jQuery库,否则Ajax无法运行

内容的提问来源于stack exchange,提问作者Kasia

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 23:45:54