Laravel中DataTables改用DELETE请求后无法删除数据行的问题排查
Laravel中使用DELETE请求删除DataTables数据失败问题分析
问题描述
原本通过GET请求可正常删除数据库数据行,改为DELETE请求并在表单中添加@csrf和@method('DELETE')后,操作失效,弹出“Data Not Deleted”错误。
相关代码片段
索引控制器生成的删除按钮
$button = ' <button type="button" name="edit" id="'.$data->id.'" class="delete btn btn-danger btn-sm"> <i class="fas fa-fw fa-trash"></i> Delete</button>';
确认删除的模态框表单
<div class="modal fade" id="confirmModal" tabindex="-1" aria-labelledby="ModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <form method="post" id="sample_form" class="form-horizontal"> @csrf @method('DELETE') <div class="modal-header"> <h5 class="modal-title" id="ModalLabel">Confirmation</h5> <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button> </div> <div class="modal-body"> <h4 align="center" style="margin:0;">Are you sure you want to remove this data?</h4> </div> <div class="modal-footer"> <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button> <button type="button" name="ok_button" id="ok_button" class="btn btn-danger">OK</button> </div> </form> </div> </div> </div>
AJAX脚本代码
var employee_id; $(document).on('click', '.delete', function(){ employee_id = $(this).attr('id'); $('#confirmModal').modal('show'); }); $('#ok_button').click(function(){ $.ajax({ url:"/admin/employees/destroy/"+employee_id, beforeSend:function(){ $('#ok_button').text('Deleting...'); }, success:function(data) { setTimeout(function(){ $('#confirmModal').modal('hide'); $('#employee_table').DataTable().ajax.reload(); alert('Data Deleted'); }, 2000); }, error: function(xhr, status, error) { setTimeout(function(){ $('#confirmModal').modal('hide'); $('#employee_table').DataTable().ajax.reload(); alert('Data Not Deleted'); }, 2000); }, }) });
路由定义
Route::delete('/admin/employees/destroy/{id}', [EmployeeController::class, 'destroy']);
控制器销毁方法
public function destroy($id) { $data = Employee::findOrFail($id); $data->delete(); }
核心原因分析
- AJAX请求未指定DELETE方法:路由定义的是
DELETE类型,但AJAX默认使用GET请求,导致路由不匹配,直接触发错误回调。 - 未携带CSRF令牌:Laravel的非GET请求必须验证CSRF令牌,AJAX请求没有携带该令牌,会被Laravel的CSRF中间件拦截,返回419错误。
- 模态框表单的令牌和方法未被利用:表单中添加的
@csrf和@method('DELETE')仅生成隐藏字段,但AJAX并未提交该表单,这些字段内容并未传到后端。
修复方案
1. 修改AJAX请求,指定方法并携带CSRF令牌
$('#ok_button').click(function(){ $.ajax({ url: "/admin/employees/destroy/"+employee_id, type: "DELETE", // 明确指定DELETE请求方法 headers: { // 从页面CSRF元标签获取令牌 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') }, beforeSend:function(){ $('#ok_button').text('Deleting...'); }, success:function(data) { setTimeout(function(){ $('#confirmModal').modal('hide'); $('#employee_table').DataTable().ajax.reload(); alert('Data Deleted'); }, 2000); }, error: function(xhr, status, error) { // 打印错误信息到控制台,方便排查具体问题 console.log(xhr.responseText); setTimeout(function(){ $('#confirmModal').modal('hide'); $('#employee_table').DataTable().ajax.reload(); alert('Data Not Deleted'); }, 2000); }, }) });
2. 确保页面头部存在CSRF元标签
在布局文件(如layouts/app.blade.php)的<head>中添加:
<meta name="csrf-token" content="{{ csrf_token() }}">
3. 优化控制器方法,返回响应
给销毁方法添加JSON响应,让前端明确操作结果:
public function destroy($id) { $data = Employee::findOrFail($id); $data->delete(); // 返回成功响应 return response()->json(['success' => '数据删除成功']); }
内容的提问来源于stack exchange,提问作者Illia
相关产品推荐
相关产品推荐

