通过 Ajax 发送 PUT、DELETE 请求的两种实现方式
一、普通请求方法发送 PUT 请求
1. 如果不用 ajax 发送 PUT,我们可以通过设置一个隐藏域设置 _method 的值,如下:
1 2 3 4 5 6 7 | <form action= "/emps" method= "post" > <input type= "hidden" name= "_method" value= "PUT" > <input type= "text" name= "username" > <input type= "password" name= "password" > <input type= "submit" /> </form> |
2. 控制层:
1 2 3 4 5 | @RequestMapping (value= "/emps" , method=RequestMethod.PUT) public String updateEmp(Employee employee) { System.out.println(employee); return "redirect:success.jsp" ; } |
注意:这里如果采用请求转发的方式即 return "success.jsp",将会出现以下问题:(Tomcat 7.0 版本不会出现这个问题)
SpringMVC HTTP Status 405 - JSPs only permit GET POST or HEAD
采用重定向的方式可以避免这个问题。
3. 这种方式发送 PUT 请求,还需在 web.xml 中配置一个 HiddenHttpMethodFilter 过滤器(如果使用Spring Boot 则会自动配置)
1 2 3 4 5 6 7 8 | <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> |
浏览器 form 表单只支持 GET 与 POST 请求,而DELETE、PUT 等 method 并不支持,Spring3.0 添加了一个过滤器,可以将这些请求转换为标准的 http 方法,使得支持 GET、POST、PUT 与 DELETE 请求。
首先看到 HiddenHttpMethodFilter 过滤器的源码:


二、通过 ajax 发送 DELETE 请求(需要带_method参数)
1 2 3 4 5 6 7 8 9 10 11 12 | /* 删除员工 */ function deleteEmp(empId){ $.ajax({ url : "emps" , data : {_method : "DELETE" , empId : empId}, type : "POST" , success : function(result){ } }) } |
发送表单 ajax 请求:
1 2 3 4 5 6 7 8 9 10 11 | $( "#updateBtn" ).click(function(){ $.ajax({ url : "emps" , data : $( "#updateEmpFormNode" ).serialize()+ "&_method=put" , type : "post" , success : function(result){ alert(result); } }) }) |
三、直接指定 ajax 请求中的 type 为 put/delete(不带 _method 参数)
1. 把上述第二点的表单更新改写为如下:
1 2 3 4 5 6 7 8 9 10 11 | $( "#updateBtn" ).click(function(){ $.ajax({ url : "emps" , data : $( "#updateEmpFormNode" ).serialize(), type : "PUT" , success : function(result){ alert(result); } }) }) |
出错:
这问题是由于 Tomcat 本身引起的,导致这个问题是因为 SpringMVC 绑定 POJO 对象时获取不到数据,然后执行更新语句时 sql 语句出错导致的。由于 POJO 的数据都为空,所以被执行的更新语句可能会为 update emp set where empId = ?,反正被执行更新语句肯定是有错的。想要知道为什么获取不到数据,下面首先先了解一下 Tomcat 如何封装数据以及SpringMVC如何绑定数据
① Tomcat 首先会将请求体中的数据,封装一个map。
② request.getParameter("empName") 就会从这个map中取值。
③ SpringMVC封装POJO对象的时候,通过 request.getParamter("empName"); 获取一个字段的值,然后赋值到 POJO 中属性名为 empName 的属性。如:
String temp = (String)request.getParamter("empName");
Employee emp = new Employee();
emp.setEmpName(temp);
查找到 protected void parseParameters() 该方法
protected String parseBodyMethods = "POST";
if( !getConnector().isParseBodyMethod(getMethod()) ) {
success = true;
return;
}
当 Tomcat 知道是请求不是 POST 请求时,会直接 return,而不会继续往下执行解析封装参数,所以当 request.getParamter("empName") 从 map 取数据时,由于 empName 参数没有被封装到 map 中,getParmater获取到值为 null。
2.1 在 web.xml 配置上HttpPutFormContentFilter;
1 2 3 4 5 6 7 8 | <filter> <filter-name>HttpPutFormContentFilter</filter-name> <filter- class >org.springframework.web.filter.HttpPutFormContentFilter</filter- class > </filter> <filter-mapping> <filter-name>HttpPutFormContentFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> |
2.2 HttpPutFormContentFilter 的作用;将请求体中的数据解析包装成一个map。
2.3 request被重新包装,request.getParameter()被重写,就会从自己封装的map中取数据
四,仍然使用PUT DELETE 请求:传递参数的时候data需要设置为json字符串
1.仍然使用put和delete请求,直接指定 ajax 请求中的 type 为 put/delete(不带 _method 参数),并且需要传递参数的时候data需要设置为json字符串。(SpringBoot环境中不需要配置任何东西,其他未知)
1 2 3 4 5 6 7 8 9 10 11 | var jsonstr = { "id" : 1 , "name" : "zsw" }; $.ajax({ url: "/update" , type: "PUT" , contentType: "application/json" , //设置请求参数类型为json字符串 data:JSON.stringify(jsonstr), //将json对象转换成json字符串发送 dataType: "json" , success:function(result){ alert(result); }, }); |
客户端需要使用@RequestBody标注
1 2 3 4 5 | @RequestMapping (value = "update" ,method = RequestMethod.PUT) public String update( @RequestBody Book book){ System.out.println(book); return BookClient.update(book); } |
我现在正在用的
//不能传表单序列化数据
var jsonstr = {"id":8,"projectName":"z"};
$.ajax({
url:"/project/update",
type:"PUT",
contentType:"application/json",//设置请求参数类型为json字符串
data:JSON.stringify(jsonstr),//将json对象转换成json字符串发送
dataType:"json",
success:function(result){
alert(result);
},
});
//对应的controller
@RequestMapping(value = "update",method = RequestMethod.PUT)
public Result updateProjectById(@RequestBody Project project){
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | var data=$("#updateForm").serialize(); console.log(data); $.ajax({ url:"/project/update", type:"POST", data : $("#updateForm").serialize()+"&_method=put", // data:{_method:"PUT"}, success:function(result){ alert("修改成功"); } }) //对应的controller @RequestMapping(value = "update",method = RequestMethod.PUT) public Result updateProjectById(Project project){ |
拓展:
Ajax请求($.ajax()为例)中data属性传参数的形式
参考链接:
https://blog.csdn.net/Mrs_Yu/article/details/92376069
https://blog.csdn.net/liuyuanjiang109/article/details/78972644
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构