Http Request中Form Data和Request Payload的区别
问题场景
在根据前端做登录跳转到后端的时候,发现username和password都输入之后提交发现提示用户名密码错误,找了半天原因发现发现传参显示的是Request Payload不是之前的form data或者request body。
最后发现是因为Content-type类型输入不对,所以对应的参数浏览器处理方式也改变了,后面修改Content-type成为"content-type: application/x-www-form-urlencoded"然后登录可以成功,而且参数处理也变成了Form Data的方式,到此问题已经解决了。那么为什么会出现这样的情况呢,想知道原因的同学可以继续看。
payload和form data区别详解
参考连接传入门Form Data和Request Payload
Content-Type不同Http处理的方式(以下内容多为搬运,版权为原作者所有原作者文章参考链接)
application-json
当提交一个ajax或者request是按照application-json, http请求格式
POST /some-path HTTP/1.1
Content-Type: application/json
{ "foo" : "bar", "name" : "John" }
在这里浏览器会展示出来请求体,但是会以payload形式呈现
application/x-www-form-urlencoded
当提交一个ajax或者request是按照Content-Type:application/x-www-form-urlencoded或者multipart/form-data, http请求格式
POST /some-path HTTP/1.1
Content-Type: application/x-www-form-urlencoded
foo=bar&name=John
这里我们看到的form-data就是request payload,在这里浏览器会把请求体按照我们熟悉的form-data的格式呈现,是因为在浏览器收到的信息里面给到了详细的信息,让浏览器按照form-data的格式
示例
在明白了Content-type会影响http传到后台的参数格式之后,我们再看看常用的几种方式会有什么区别
form表单
我们首先看一下Html form是怎么处理的
<form action="/" method="POST">
<input name="name" type="text">
<input name="password" type="text">
<button>提交</button>
</form>
可以看到html form会按照Content-type:application/x-www-form-urlencoded来处理请求
ajax
传统的ajax
function submit2() {
var xhr = new XMLHttpRequest();
xhr.timeout = 3000;
var obj = {a: 1, b: 2};
xhr.open('POST', '/');
xhr.send(obj);
}
默认的Content-Type为text/plain,然后会按照request payload处理请求
axios
由于axios已经是vue、react的准标配请求方式了,所以这里探究一下它。
function submit3() {
var sence1 = 'name=123&val=456';
var sence2 = {name: 123, val: 456};
axios.post('/', sence1)
}
分别传递字符串与对象,提交post请求,然后观察结果:
场景1——传递字符串时候的结果:
场景2——传递对象的结果:
最终可以看到:
1.当我们传递字符串的时候,Content-Type自动转为xxx-form-xxx的形式。当为对象的时候,自动转化为xxx/json。
2.字符串的时候以key1=val1&key2=val2的形式体现,对象以JSON字符串形式体现。
###结论
1.传统的ajax请求时候,Content-Type默认为"文本"类型。
2.传统的form提交的时候,Content-Type默认为"Form"类型。
3.axios传递字符串的时候,Content-Type默认为"Form"类型。
4.axios传递对象的时候,Content-Type默认为"JSON"类型
小记总结
其实不论是那种content-type其实后台都会拿到参数,但是按照form的格式提交,后端spring处理请求会根据key-value(或者说request param和reqeust body)的方式匹配我们的参数,但是如果content-type没有指定form那么就会post按照json的方式传入到后台,这时候我们如果自己去在后台解析json也可以处理但是一般我们都直接使用spring封装好的方式来处理,不会去自己解析json,所以一般都传form类型到后台接口。