Jquery Ajax向Laravel PUT路由请求时FormData为空问题排查
问题描述
在home.blade.php页面中,接收控制器传递的users数据循环展示,页面包含Bootstrap模态框。点击Edit按钮时,通过JQuery与JavaScript混合代码将用户旧数据填充到模态框表单;点击Confirm按钮时,JQuery Ajax脚本向控制器发送PUT请求更新用户数据,但出现服务器错误——对null调用update()方法。排查发现formData为空,导致请求无数据传递,不清楚为何const form = $('#editForm')[0]; const formData = new FormData(form);无法正常工作。
Blade代码
@extends('layouts.app') @section('content') <table class="table" id="table" > @foreach($users as $user) <tr> <th>Student Name</th> <th>Email</th> <th>Active</th> </tr> <tr> <td>{{$user->username}}</td> <td>{{$user->email}}</td> <td>{{$user->active ? 'Active' : 'Inactive'}}</td> <td style="width: 40px"><button data-username="{{$user->username}}" data-email="{{$user->email}}" data-active="{{$user->active}}" data-id="{{$user->id}}" type="button" class="btn btn-primary edit" data-bs-toggle="modal" data-bs-target="#exampleModal">Edit</button></td> <td style="width: 40px"><button type="button" class="btn btn-danger">Delete</button></td> <td style="width: 40px"><button type="button" class="btn btn-warning">{{$user->active ? 'Activate' : 'Deactivate'}}</button></td> </tr> @endforeach </table> <div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" style="margin-top: 200px"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <form id="editForm"> <input id="username" type="text" name="username" class="form-control" > <label for="email" class="form-label">email</label> <input id="email" type="text" name="email" class="form-control" > <input type="hidden" id="id" name="id"> <div class="mt-4"> <button type="button" class="btn btn-secondary me-2" data-bs-dismiss="modal">Close</button> <button id="activateStatus" type="button" class=" btn btn-primary me-2"></button> <button id="button" class="btn btn-primary me-2">Confirm</button> </div> </div> </form> </div> </div> </div>
JavaScript代码
const table = document.querySelector("#table"); table.addEventListener("click", (e) => { if (e.target.classList.contains("edit")) { $("#id").val(e.target.dataset.id); $("#username").val(e.target.dataset.username); $("#email").val(e.target.dataset.email); $("#activateStatus").text( Number(e.target.dataset.active) ? "Deactivate" : "Activate", ); } }); $(document).ready(function () { $.ajaxSetup({ headers: { "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"), }, }); $("#editForm").submit(function (e) { e.preventDefault(); const form = $("#editForm")[0]; const formData = new FormData(form); $.ajax({ type: "PUT", url: '{{route("edit")}}', data: formData, processData: false, contentType: false, success: function (response) { console.log(response); }, error: function (errResponse) { console.log(errResponse); }, }); }); });
问题修复方案
1. 修正表单HTML结构错误
原代码中modal-body的闭合标签</div>被错误地放在了</form>内部,导致浏览器解析时表单没有正确包裹所有输入控件,FormData无法读取到表单元素的值。
修复后的模态框代码:
<div class="modal fade" id="exampleModal" tabindex="-1" aria-labelledby="exampleModalLabel" aria-hidden="true"> <div class="modal-dialog" style="margin-top: 200px"> <div class="modal-content"> <div class="modal-header"> <h5 class="modal-title" id="exampleModalLabel">Modal title</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <form id="editForm"> <input id="username" type="text" name="username" class="form-control"> <label for="email" class="form-label">email</label> <input id="email" type="text" name="email" class="form-control"> <input type="hidden" id="id" name="id"> <div class="mt-4"> <button type="button" class="btn btn-secondary me-2" data-bs-dismiss="modal">Close</button> <button id="activateStatus" type="button" class="btn btn-primary me-2"></button> <button id="button" type="submit" class="btn btn-primary me-2">Confirm</button> </div> </form> </div> <!-- 将modal-body的闭合标签移到form外面 --> </div> </div> </div>
2. 将Confirm按钮改为提交类型
原Confirm按钮的type为button,不会触发表单的submit事件,导致绑定的表单提交回调无法执行。需要将按钮的type属性改为submit。
3. 额外优化建议
- 表格表头应放在
foreach循环外部,避免每个用户重复生成表头:
<table class="table" id="table" > <tr> <th>Student Name</th> <th>Email</th> <th>Active</th> <th>Actions</th> </tr> @foreach($users as $user) <tr> <td>{{$user->username}}</td> <td>{{$user->email}}</td> <td>{{$user->active ? 'Active' : 'Inactive'}}</td> <td style="width: 160px"> <button data-username="{{$user->username}}" data-email="{{$user->email}}" data-active="{{$user->active}}" data-id="{{$user->id}}" type="button" class="btn btn-primary edit btn-sm" data-bs-toggle="modal" data-bs-target="#exampleModal">Edit</button> <button type="button" class="btn btn-danger btn-sm">Delete</button> <button type="button" class="btn btn-warning btn-sm">{{$user->active ? 'Deactivate' : 'Activate'}}</button> </td> </tr> @endforeach </table>
- 可以在JS中添加调试代码,验证
formData是否正确获取数据:
$("#editForm").submit(function (e) { e.preventDefault(); const form = $("#editForm")[0]; const formData = new FormData(form); // 打印formData内容 for (let [key, value] of formData.entries()) { console.log(`${key}: ${value}`); } // 后续Ajax代码... });
内容的提问来源于stack exchange,提问作者ahmad kharabsheh
相关产品推荐
相关产品推荐

