news 2026/10/28 10:22:56

Spring MVC 删除功能:用隐藏表单模拟 DELETE 请求的完整解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Spring MVC 删除功能:用隐藏表单模拟 DELETE 请求的完整解析

Spring MVC 删除功能:用隐藏表单模拟 DELETE 请求的完整解析

原始代码

<script>functiondel(event){event.preventDefault();if(confirm("确定要删除吗?")){letuserform=document.querySelector("#userForm");userform.action=event.target.href;userform.submit();}}</script><formid="userForm"method="post"><inputtype="hidden"name="_method"value="delete"/></form>

一、这段代码解决什么问题

浏览器中的超链接<a>只能发起GET请求,HTML 表单原生只支持GET和POST。而 RESTful 风格的删除操作要求使用DELETE方法。

这段代码的做法是:

  1. 点击“删除”链接时,先阻止链接默认的 GET 跳转。
  2. 弹出确认框,用户确认后才继续。
  3. 找到一个隐藏的 POST 表单,把表单的提交地址改成删除链接的地址。
  4. 提交这个 POST 表单,同时携带_method=delete。
  5. 服务端的HiddenHttpMethodFilter读取_method,把 POST 改写成 DELETE。
  6. Spring MVC 用@DeleteMapping匹配并执行删除。

一句话概括:用超链接提供删除地址,用隐藏表单以 POST 方式提交,再用_method把 POST 伪装成 DELETE。

二、逐行代码解释

1. 定义删除函数

functiondel(event){

del是自定义函数名,绑定在删除链接的onclick事件上。参数event是浏览器传入的事件对象,包含触发事件的元素、默认行为等信息。

2. 阻止链接默认跳转

event.preventDefault();

超链接<a href="...">被点击时,浏览器默认会发起 GET 请求并跳转页面。preventDefault()取消这个默认行为,否则页面会先跳走,后面的表单提交逻辑无法执行。

这一行必须放在函数最前面。

3. 弹出确认框

if(confirm("确定要删除吗?")){

confirm()是浏览器内置的阻塞式确认框,返回布尔值:

  • 点击“确定”返回true。
  • 点击“取消”返回false。

只有返回true时才进入 if 内部执行删除提交。用户取消时,函数结束,不会发生任何请求。前端确认只是防误触,不能替代后端权限和参数校验。

4. 找到隐藏表单

letuserform=document.querySelector("#userForm");

document.querySelector("#userForm")根据 id 查找页面中的表单元素。

对应的表单是:

<formid="userForm"method="post">

querySelector返回第一个匹配的元素。这里要求页面中id="userForm"唯一,否则可能选错表单。

5. 修改表单提交地址

userform.action=event.target.href;

event.target是触发事件的元素,也就是被点击的删除链接。href是这个链接的目标地址,例如:

http://localhost:8080/usermgt/user/1

这一行把隐藏表单的action设置为该地址。表单原本没有写action,提交时会默认提交到当前页面;动态赋值后,提交目标就变成了删除链接指向的 URL。

更稳妥的写法是event.currentTarget.href:

userform.action=event.currentTarget.href;

区别在于:如果<a>内部还有<span>、<i>等子元素,用户点到的可能是子元素,event.target会指向子元素而不是<a>,子元素没有href。event.currentTarget始终指向绑定事件的<a>元素。

6. 提交表单

userform.submit();

调用表单的原生submit()方法,立即以表单的method提交。这里的method是post,所以浏览器发出的是 POST 请求。

注意:form.submit()不会触发onsubmit事件。如果表单上有onsubmit校验,这里不会执行。当前表单只有隐藏字段,不需要额外校验。

7. 隐藏的_method字段

<inputtype="hidden"name="_method"value="delete"/>

这是整个方案的关键。浏览器提交的是 POST,但请求参数里带了一个_method=delete。

服务端配置HiddenHttpMethodFilter后,过滤器会读取这个参数,把请求方法从 POST 改写成 DELETE。Spring MVC 随后按照 DELETE 方法去匹配@DeleteMapping。

传统web.xml中需要配置:

<filter><filter-name>hiddenHttpMethodFilter</filter-name><filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class></filter><filter-mapping><filter-name>hiddenHttpMethodFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

Spring Boot 中默认关闭,需要显式开启:

spring:mvc:hiddenmethod:filter:enabled:true

三、完整使用示例

删除链接通常写在表格的每一行中:

<trth:each="user : ${users}"><tdth:text="${user.id}"></td><tdth:text="${user.username}"></td><td><ath:href="@{/user/{id}(id=${user.id})}"onclick="del(event)">删除</a></td></tr><formid="userForm"method="post"><inputtype="hidden"name="_method"value="delete"/></form>

假设用户 id 是 1,th:href渲染为:

/usermgt/user/1

点击删除后:

  1. preventDefault()阻止链接跳转。
  2. 确认框弹出。
  3. 表单action被设置为http://localhost:8080/usermgt/user/1。
  4. 表单以 POST 提交,参数包含_method=delete。
  5. 过滤器把 POST 改写成 DELETE。
  6. Spring MVC 匹配@DeleteMapping("/user/{id}")。

后端方法示例:

@DeleteMapping("/user/{id}")publicStringdeleteUser(@PathVariableLongid){userService.deleteById(id);return"redirect:/user";}

四、执行流程图

点击删除链接 │ ▼ preventDefault() 阻止 GET 跳转 │ ▼ confirm() 弹出确认框 │ ├── 取消 → 函数结束,无请求 │ └── 确定 │ ▼ querySelector("#userForm") 找到隐藏表单 │ ▼ form.action = 链接的 href │ ▼ form.submit() 以 POST 提交 │ ▼ 请求携带 _method=delete │ ▼ HiddenHttpMethodFilter 把 POST 改写为 DELETE │ ▼ DispatcherServlet 匹配 @DeleteMapping("/user/{id}") │ ▼ 执行删除,重定向到列表

五、常见问题与注意事项

1. 忘记配置HiddenHttpMethodFilter

如果过滤器没生效,服务端收到的仍然是 POST,@DeleteMapping匹配不到,返回 405。日志里会看到:

POST "/usermgt/user/1" HttpRequestMethodNotSupportedException

2. 表单method写成 GET

<formid="userForm"method="get">

这样提交的是 GET,_method不会按预期生效。必须使用method="post"。

3.event.target.href取不到地址

如果删除链接内部有子元素,event.target可能是子元素。改为:

userform.action=event.currentTarget.href;

4. 表单 id 重复

页面中如果有多个id="userForm",querySelector只会返回第一个,可能导致提交到错误的地址。确保 id 唯一。

5. 路径与后端映射不一致

链接href生成的路径必须和@DeleteMapping完全匹配。例如后端是:

@DeleteMapping("/user/{id}")

链接就应该是/user/1。如果链接是/user,后端却要求/user/{id},会 405 或 404。

6. 前端确认不是安全机制

confirm()只是防误触。真正的权限校验、存在性校验、关联数据检查必须在后端完成。

7. Spring Security 下的 CSRF

如果项目启用了 Spring Security,POST 表单需要携带 CSRF token,否则会被拒绝。隐藏表单中需要额外加:

<inputtype="hidden"th:name="${_csrf.parameterName}"th:value="${_csrf.token}"/>

六、为什么不用 AJAX 或直接 GET 删除

方案是否推荐原因
<a href="/delete?id=1">GET 删除不推荐GET 应该是安全的、幂等的,爬虫和预加载可能误触发删除
隐藏表单 +_method推荐不依赖 JavaScript 框架,传统 MVC 项目常用
fetch/axios发 DELETE推荐前后端分离项目更常见,控制更灵活

这段代码属于传统服务端渲染项目的经典做法,适合 Thymeleaf + Spring MVC 的表单场景。

七、记忆方法

1. 四步口诀

拦默认,问确认,改地址,交表单。

对应:

preventDefault → confirm → action = href → submit

2. 表单三要素

id 要唯一, method 用 post, _method 写 delete。

3. 链路五步

点击链接 → 阻止跳转 → 确认 → 表单改地址 → POST 带 _method → 过滤器改写 DELETE → @DeleteMapping 匹配

4. 两个容易记错的地方

event.target 可能不是链接,改用 currentTarget 更稳。 form.submit() 不会触发 onsubmit。

5. 一句话总结

链接只负责提供地址,表单负责发 POST,_method负责把 POST 变成 DELETE,过滤器负责改写,后端@DeleteMapping负责接收。

八、总结

代码片段作用注意事项
event.preventDefault()阻止链接默认 GET 跳转必须放在函数最前
confirm(...)删除前确认只是防误触,不是安全机制
querySelector("#userForm")找到隐藏表单id 必须唯一
userform.action = href设置提交地址用currentTarget更稳
userform.submit()以 POST 提交不触发onsubmit
_method=delete让过滤器把 POST 改写为 DELETE需要HiddenHttpMethodFilter
method="post"表单提交方式不能写成 GET

这段代码的核心是“用 POST 模拟 DELETE”。前端用隐藏表单绕开浏览器对 DELETE 的限制,后端用过滤器还原真实方法,Spring MVC 再用@DeleteMapping匹配。记住“拦、问、改、交”四步,以及“id 唯一、method 是 post、_method是 delete”三要素,这类删除功能就能独立写出来。最容易出错的地方是过滤器没开、表单 method 写成 GET、路径和后端映射不一致。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/28 10:22:36

酶活性:催化反应的“精准标尺”,读懂活性蛋白的转化密码

引言&#xff1a;蛋白质家族中的“催化剂”活性蛋白根据其功能特性&#xff0c;通常可分为三大类&#xff1a;结合类蛋白&#xff08;以特异性识别与结合为核心功能&#xff0c;如抗体、受体、配体&#xff09;、调控类蛋白&#xff08;负责调节细胞增殖、分化、迁移等行为&…

作者头像 李华
网站建设 2026/10/28 10:21:24

采矿智能机器人(7 种)

U-C-01 采煤工作面智能机器人群目录基本要求&#xff08;摘编&#xff09;&#xff1a;采煤机、刮板机、液压支架、转载、超前支架自主协同&#xff0c;煤岩界面识别。 主要AI 失效模式&#xff1a;支架落后造成空顶&#xff1b;采煤机割支架&#xff1b;人误入刮板&#xff1b…

作者头像 李华
网站建设 2026/10/28 10:21:22

动手学深度学习(李沐)——现代循环神经网络读书笔记

矩阵连续乘积可以导致梯度消失或梯度爆炸的问题。这导致我们的循环网络不能太长&#xff0c;但是在循环神经网络中早期观测值对预测所有未来观测值可能具有非常重要的意义&#xff0c;同时一些词元也可能没有相关的观测值。这里我们介绍以下现代循环神经网络解决这些问题。1.门…

作者头像 李华
网站建设 2026/10/28 10:21:11

2027年主流降AI工具对比:10款降AI率软件选型与复核

2027年主流降AI工具对比&#xff1a;10款降AI率软件选型与复核【工具功能与核对要点】BunnyScholar&#xff1a;比较长文处理与术语保留情况&#xff0c;逐段核对学术论证、引用和原意。助研君&#xff1a;比较分段处理、输出质量与费用&#xff0c;修改后保留版本并人工复核。…

作者头像 李华
网站建设 2026/10/28 10:21:07

2027年12款主流降AI率工具大汇总:论文降AIGC功能与复核指南

2027年12款主流降AI率工具大汇总&#xff1a;论文降AIGC功能与复核指南【自查与修订要点】先确认学校的检测范围、具体要求与提交期限。保存原稿、报告、研究笔记与版本记录。依据研究材料核对论证、术语、公式和引用。使用辅助工具前查看学校规定、费用与隐私条款。论文AIGC自…

作者头像 李华
网站建设 2026/10/28 10:20:02

隧道安全管理系统都管些啥?搞懂这六块,跟厂家谈才不被忽悠

跟隧道项目部打交道多了&#xff0c;经常听到一句话&#xff1a;"你们那系统到底管什么&#xff1f;"一问&#xff0c;有的厂家能说半小时&#xff0c;有的三句话讲不清。其实隧道安全管理系统说穿了就六块&#xff0c;今天把家底给你摆开讲。这是系统的"眼睛&q…

作者头像 李华