chrome-dev-tools中Form Data与Request Payload有什么区别?

在前后端联调过程中,常常会遇到前端同学说“明明向后端传递了数据,怎么后端接收不到呢?”为了解决这个困扰,本文来分析下究竟是什么导致了上述问题。

前后端联调时常会F12打开调试器分析请求,在request body中通常会看到Form DataRequest Payload两种形式。

image.png

image.png

场景

  • 使用axios发送post请求,参数为对象,默认会设置Content-Typeapplication/json

chrome-dev-tools中Form Data与Request Payload有什么区别?_第1张图片

  • 使用axios发送post请求,参数为对象,手动设置Content-Typeapplication/x-www-form-urlencoded

chrome-dev-tools中Form Data与Request Payload有什么区别?_第2张图片

  • 使用axios发送get请求,默认会设置Content-Typeapplication/x-www-form-urlencoded

chrome-dev-tools中Form Data与Request Payload有什么区别?_第3张图片

  • 使用form表单发送get请求,encType设置为application/x-www-form-urlencoded如果没有设置encType,默认值为application/x-www-form-urlencoded。会自动对表单数据URL编码,并以键值对形式追加到请求url后面,表单提交后会跳转到新url。如果这种形式上传文件肯定是不行的,将文件对象转化成Data url然后追加到url后面,如果文件比较大,data url也会很长,追加到url后面可能会超出url最大长度。

chrome-dev-tools中Form Data与Request Payload有什么区别?_第4张图片

  • 使用form表单发送post请求,encType设置为application/x-www-form-urlencoded。会自动对表单数据URL编码,并编码成键值对形式。如果以这种形式上传文件,传输性能比较差(字符传输性能比二进制传输性能差)。

chrome-dev-tools中Form Data与Request Payload有什么区别?_第5张图片

  • 使用form表单发送post请求,encType设置为multipart/form-data

chrome-dev-tools中Form Data与Request Payload有什么区别?_第6张图片

  • 使用FormData封装数据,axios发送post请求,Content-Type设置为multipart/form-data

chrome-dev-tools中Form Data与Request Payload有什么区别?_第7张图片

tomcat对请求参数做了一些处理

详情可以参考这两篇文章,结合起来看可以得出下面结论
tomcat的servlet读取请求参数
tomcat源码---->request的请求参数分析

1、对于get请求参数,tomcat会将参数以键值对形式放进一个名叫paramHashValuesMap中,后端通过request.getParameter(name)取的就是paramHashValues里面的数据,或者使用springMVC中的@RequestParam
chrome-dev-tools中Form Data与Request Payload有什么区别?_第8张图片

2、对于post请求,Content-Typeapplication/x-www-form-urlencoded,请求参数也会放进一个名叫paramHashValuesMap中,后端通过request.getParameter(name)取的就是paramHashValues里面的数据,或者使用springMVC中的@RequestParam

3、对于post请求,Content-Typemultipart/form-datatomcat通过request.getInputStream().read()读取请求数据流,然后放入到paramHashValues当中。后端可以通过((MultipartHttpServletRequest) request).getFiles("file")来获取上传文件对象,至于其他的表单参数,通过((MultipartHttpServletRequest) request).getParameter(name)来获取,或者使用springMVC中的@RequestParam以及MultipartFile来获取:
chrome-dev-tools中Form Data与Request Payload有什么区别?_第9张图片

4、对于post请求,Content-Typeapplication/json,不会将请求参数放入到paramHashValues当中,因此request.getParameter(name)是获取不到参数值。需要通过注解@RequestBody来接收参数。

因此,后端为什么接收不到前端传的参数,主要是因为前端设置的Content-Type与后端接收参数的方式(request.getParameter(name)或者其他)不一致。

附上@RequestBody和@RequestParam区别

实际项目中的一些场景

1. post请求,Content-Typeapplication/x-www-form-urlencoded
chrome-dev-tools中Form Data与Request Payload有什么区别?_第10张图片
chrome-dev-tools中Form Data与Request Payload有什么区别?_第11张图片
2、post请求,Content-Typeapplication/json
image.png
chrome-dev-tools中Form Data与Request Payload有什么区别?_第12张图片
3、form表单post请求,默认Content-Typeapplication/x-www-form-urlencoded
chrome-dev-tools中Form Data与Request Payload有什么区别?_第13张图片
chrome-dev-tools中Form Data与Request Payload有什么区别?_第14张图片
4、form表单post请求,Content-Type为multipart/form-data
chrome-dev-tools中Form Data与Request Payload有什么区别?_第15张图片
chrome-dev-tools中Form Data与Request Payload有什么区别?_第16张图片

你可能感兴趣的:(formdata)