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
相关产品推荐
相关产品推荐

