Http Request中Form Data和Request Payload的区别

Scroll Down

Http Request中Form Data和Request Payload的区别

问题场景

在根据前端做登录跳转到后端的时候,发现username和password都输入之后提交发现提示用户名密码错误,找了半天原因发现发现传参显示的是Request Payload不是之前的form data或者request body。
企业微信20200718020050.png
最后发现是因为Content-type类型输入不对,所以对应的参数浏览器处理方式也改变了,后面修改Content-type成为"content-type: application/x-www-form-urlencoded"然后登录可以成功,而且参数处理也变成了Form Data的方式,到此问题已经解决了。那么为什么会出现这样的情况呢,想知道原因的同学可以继续看。
企业微信20200718020707.png

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>

9669593565ca77f1b807cc_articlex.png
可以看到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);
}

1001047265ca781280c9c5_articlex.png
默认的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——传递字符串时候的结果:
7454328015ca78278dfc95_articlex.png
场景2——传递对象的结果:
10109288585ca782ed4338b_articlex.png
最终可以看到:
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类型到后台接口。