在前后端联调过程中,常常会遇到前端同学说“明明向后端传递了数据,怎么后端接收不到呢?”为了解决这个困扰,本文来分析下究竟是什么导致了上述问题。
前后端联调时常会F12打开调试器分析请求,在request body
中通常会看到Form Data
与Request Payload
两种形式。
场景
- 使用
axios
发送post
请求,参数为对象,默认会设置Content-Type
为application/json
。
- 使用
axios
发送post
请求,参数为对象,手动设置Content-Type
为application/x-www-form-urlencoded
。
- 使用
axios
发送get
请求,默认会设置Content-Type
为application/x-www-form-urlencoded
。
- 使用
form
表单发送get
请求,encType
设置为application/x-www-form-urlencoded
,如果没有设置encType
,默认值为application/x-www-form-urlencoded
。会自动对表单数据URL
编码,并以键值对形式追加到请求url
后面,表单提交后会跳转到新url。如果这种形式上传文件肯定是不行的,将文件对象转化成Data url
然后追加到url
后面,如果文件比较大,dataurl
也会很长,追加到url
后面可能会超出url
最大长度。
- 使用
form
表单发送post
请求,encType
设置为application/x-www-form-urlencoded
。会自动对表单数据URL
编码,并编码成键值对形式。如果以这种形式上传文件,传输性能比较差(字符传输性能比二进制传输性能差)。
- 使用
form
表单发送post
请求,encType
设置为multipart/form-data
。
- 使用
FormData
封装数据,axios
发送post
请求,Content-Type
设置为multipart/form-data
。
tomcat对请求参数做了一些处理
详情可以参考这两篇文章,结合起来看可以得出下面结论
tomcat的servlet读取请求参数
tomcat源码---->request的请求参数分析
1、对于get
请求参数,tomcat
会将参数以键值对形式放进一个名叫paramHashValues
的Map
中,后端通过request.getParameter(name)
取的就是paramHashValues
里面的数据,或者使用springMVC
中的@RequestParam
。
2、对于post
请求,Content-Type
为application/x-www-form-urlencoded
,请求参数也会放进一个名叫paramHashValues
的Map
中,后端通过request.getParameter(name)
取的就是paramHashValues
里面的数据,或者使用springMVC
中的@RequestParam
。
3、对于post
请求,Content-Type
为multipart/form-data
,tomcat
通过request.getInputStream().read()
读取请求数据流,然后放入到paramHashValues
当中。后端可以通过((MultipartHttpServletRequest) request).getFiles("file")
来获取上传文件对象,至于其他的表单参数,通过((MultipartHttpServletRequest) request).getParameter(name)
来获取;或者使用springMVC
中注解@RequestParam
和MultipartFile
来接收:
4、对于post
请求,Content-Type
为application/json
,不会将请求参数放入到paramHashValues
当中,因此request.getParameter(name)
是获取不到参数值。需要通过注解@RequestBody
来接收参数。
因此,后端为什么接收不到前端传的参数,主要是因为前端设置的Content-Type
与后端接收参数的方式(request.getParameter(name)
或者其他)不一致。
附上@RequestBody和@RequestParam区别
实际项目中的一些场景
1. post
请求,Content-Type
为application/x-www-form-urlencoded
2、post
请求,Content-Type
为application/json
3、form
表单post
请求,默认Content-Type
为application/x-www-form-urlencoded
4、form
表单post
请求,Content-Type为multipart/form-data
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。