HTTP请求中的Form Data与Request Payload的区别

Request Payload VS Form Data

前端请求

我看了前端发起的请求,请求正文并不是我熟悉的 Form Data,而是 Request Payload。如图注意下面两个请求的 Content-Type 的区别。

Request Payload 请求

HTTP请求中的Form Data与Request Payload的区别

Form Data 请求

HTTP请求中的Form Data与Request Payload的区别

了解这两个的区别之前,我们先回顾下 HTTP 请求报文格式:

Request Payload 大概格式如下,请求头部的 Content-Type: application/json,并且请求正文是一个 json 格式的字符串

HTTP请求中的Form Data与Request Payload的区别

Form Data 大概格式如下,请求头部的 Content-Type: application/x-www-form-urlencoded,并且请求正文是类似 get 请求 url 的请求参数

HTTP请求中的Form Data与Request Payload的区别

后台处理

对于 Request Payload 请求, 必须加 @RequestBody 才能将请求正文解析到对应的 bean 中,且只能通过 request.getReader() 来获取请求正文内容

HTTP请求中的Form Data与Request Payload的区别

对于 Form Data 请求,无需任何注解,springmvc 会自动使用 MessageConverter 将请求参数解析到对应的 bean,且通过 request.getParameter(...) 能获取请求参数

HTTP请求中的Form Data与Request Payload的区别

解决方案

综上,我在前端选择使用 Form Data 的方式来发起请求,使用 qs 库将 json 对象转化为字符串 (如 {name:‘dahuang‘,age: 11} 转化为 name=dahuang&age=11)。
之前我以为 axios 会自动根据你的请求正文格式来选择发起 Form Data 还是 Request Payload 请求,但是执行 delete 操作时,如图的 Content-Type 却是 text/plain

HTTP请求中的Form Data与Request Payload的区别

所以,通过通过下面的方面来解决

HTTP请求中的Form Data与Request Payload的区别

一个奇怪的问题

执行 delete 操作时,我将 axios 添加了 headers,content-type: ‘application/x-www-form-unlencoded‘,请求如图,但是后台 springmvc 的 @DeleteMapping 接收不到请求参数,必须使用 @RequestParam String id,才能接收到请求参数。看了这个回答,有人回复说这个是 tomcat 的问题而非 spring 的问题。

HTTP请求中的Form Data与Request Payload的区别

更新,今天遇到了一个问题,突然我的 @PatchMapping 也不能获取 form 表单传递的参数了。之前是可以的,然后我 google 搜到了 HttpPutFormContentFilter,然后发现这个 filter 在 WebMvcAutoConfiguration 里面配置的,而这个配置生效其中有一个条件是 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class),恰好,我前两天整合前端代码的时候配置 springMVC 继承了 WebMvcConfigurationSupport.class 所以导致了该 fliter 不生效。

相关推荐