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

调用DELETE请求时出现HTTP 405错误:GET方法不支持的排查求助

问题:DataTable行删除功能触发405错误(GET请求不被支持)

我尝试为DataTable的每一行实现删除功能:通过触发Bootstrap模态框,向Spring控制器发送携带username参数的DELETE请求。但实际请求未路由到对应控制器,而是弹出错误:HTTP Status 405 - Request method 'GET' not supported。

相关代码:

JS代码:

$(document).ready(function () {
 $('#usersTable').DataTable({
 "sAjaxSource": "users/list",
 "sAjaxDataProp": "",
 "aoColumns": [
 {"mData": "username"},
 {"mData": "firstName"},
 {"mData": "lastName"},
 {"mData": "status"},
 {"mData": "role.roleName"},
 {
 mRender: function (data, type, row) {
 var linkDel = "<a href=\"#\" onclick=\"fillDeleteFrm('username')\">Delete</a>";
 linkDel = linkDel.replace("id", row.id);
 linkDel = linkDel.replace("name", row.name);
 return linkDel;
 }
 }
 ]
 })
});
function fillDeleteFrm(username) {
 $('#delete-username').val(username);
 $('#userDeleteModal').modal('toggle');
 return false;
}

Thymeleaf表单代码:

<div id="userDeleteModal">
 <form id="systemUserForm" th:action="@{/userdelete}" th:method="delete">
 <input type="hidden" id="delete-username" name="username" th:value="*{username}">
 <button type="submit" class="btn btn-primary">Delete</button>
 </div>
 </form>

Spring控制器代码:

@ResponseBody
@RequestMapping(value="/userdelete", method = RequestMethod.DELETE)
public ModelAndView deleteEmployee(@RequestParam String username) {
 User user = userService.findUserByUserName(username);
 userService.deleteUser(user);
 return new ModelAndView("users");
}

错误原因分析

  1. HTML表单的方法限制:HTML原生表单只支持GET和POST两种请求方法,你在Thymeleaf里写的th:method="delete",最终浏览器会默认发送GET请求,而你的控制器只接受DELETE方法,所以触发405错误。
  2. JS参数传递错误:你的删除链接生成代码里,fillDeleteFrm('username')传递的是字符串'username',而不是当前行的实际username值;另外后面的replace("id", row.id)和replace("name", row.name)完全是无效操作,因为原字符串里根本没有id或name这两个子串。

具体修复步骤

1. 修复JS中的删除链接生成逻辑

把mRender里的代码改成正确传递当前行的username:

mRender: function (data, type, row) {
 // 直接把row.username传入fillDeleteFrm函数
 return "<a href=\"#\" onclick=\"fillDeleteFrm('" + row.username + "'); return false;\">Delete</a>";
}

这样点击删除链接时,会把当前行的真实用户名传递给模态框的表单。

2. 调整Thymeleaf表单,模拟DELETE请求

因为HTML不支持直接发送DELETE,我们需要用POST请求配合Spring的HiddenHttpMethodFilter来模拟DELETE:

<div id="userDeleteModal" class="modal fade">
 <div class="modal-dialog">
  <div class="modal-content">
   <form id="systemUserForm" th:action="@{/userdelete}" th:method="post">
    <!-- 添加隐藏字段来告诉Spring这是DELETE请求 -->
    <input type="hidden" name="_method" value="delete"/>
    <input type="hidden" id="delete-username" name="username" th:value=""/>
    <div class="modal-footer">
     <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
     <button type="submit" class="btn btn-danger">Delete</button>
    </div>
   </form>
  </div>
 </div>
</div>

注意:如果是Spring Boot项目,HiddenHttpMethodFilter默认已经启用;如果是传统Spring MVC项目,需要在web.xml中手动配置这个过滤器。

3. 优化控制器(可选)

你的控制器用了@ResponseBody但返回了ModelAndView,这有点矛盾。如果是页面跳转,不需要@ResponseBody;如果是AJAX请求,应该返回JSON格式的结果。如果保持页面跳转的话,修改控制器:

@RequestMapping(value="/userdelete", method = RequestMethod.DELETE)
public String deleteEmployee(@RequestParam String username) {
 User user = userService.findUserByUserName(username);
 userService.deleteUser(user);
 // 重定向到用户列表页面,避免表单重复提交
 return "redirect:/users/list";
}

4. 可选:用AJAX发送DELETE请求(更优雅)

如果不想用表单提交,直接用AJAX发送DELETE请求,这样不需要模态框的表单,体验更好:

// 修改JS的mRender
mRender: function (data, type, row) {
 return "<a href=\"#\" onclick=\"deleteUser('" + row.username + "'); return false;\">Delete</a>";
}

// 添加删除函数
function deleteUser(username) {
 if(confirm("确定要删除用户 " + username + " 吗?")) {
  $.ajax({
   url: "/userdelete",
   type: "DELETE",
   data: {username: username},
   success: function() {
    // 重新加载DataTable数据
    $('#usersTable').DataTable().ajax.reload();
    alert("删除成功");
   },
   error: function() {
    alert("删除失败");
   }
  });
 }
}

这种方式下,控制器可以返回JSON:

@ResponseBody
@RequestMapping(value="/userdelete", method = RequestMethod.DELETE)
public Map<String, Object> deleteEmployee(@RequestParam String username) {
 Map<String, Object> result = new HashMap<>();
 try {
  User user = userService.findUserByUserName(username);
  userService.deleteUser(user);
  result.put("success", true);
 } catch (Exception e) {
  result.put("success", false);
  result.put("message", e.getMessage());
 }
 return result;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:41:22