Crispin's Blog

payload和formData有什么不同?

最近做项目的时候,在通过post请求向服务端发送数据的时候,请求失败了。错误信息如下:

400错误截图

返回的400(bad request)错误,说明客户端这边发送的请求是有问题的。

和通过jquery中的ajax方法发送的请求作对比,发现问题出在了请求的主体部分。

这里的请求主体部分是payload的形式的。

payload请求主体截图

而直接通过jq,是如下这种formData形式。

formData请求主体截图

formData是什么?

formData是客户端主体部分组装数据的一种方式,当我们使用:

  1. method='POST' 提交一个HTML-Form表单
  2. Content-Type: application/x-www-form-urlencoded
  3. Content-Type: multipart/form-data

这三种方式去提交请求主体的时候,就是formData形式。

将如上的请求简写一下:

1
2
3
4
5
起始行: POST /getProduct HTTP/1.1
首部: Content-Type: application/x-www-form-urlencoded

主体1:productId=3189 # 单参
主体2:productId=3189&orderId=145 # 多参

主体的形式会有两种,在多参数的情况下,和get请求一样,是用&进行连接的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
$.ajax({
url: "/v2/product/getProductProp",
data: { productId: proid },
type: "post",
})
.then(function (data) {
/* TODO */
})
.fail(function () {
that.fetchDataFailed();
})
.done(function () {
/* TODO */
});

在jq的ajax模块中,contentType默认使用的是formData发送主体的。既然如此,我们就通过传入自定义的contentType:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$.ajax({
url: "/v2/product/getProductProp",
data: { productId: proid },
type: "post",
contentType: "application/json", // 注意这里的不同
})
.then(function (data) {
/* TODO */
})
.fail(function () {
that.fetchDataFailed();
})
.done(function () {
/* TODO */
});

修改contentType后变为payload截图

是的,我们确实成功的修改了formData的提交形式,变成了payload。

payload是什么?

payload是一种以JSON格式进行数据传输的一种方式。

http可能会传输payload,如果不限制其请求的方式(那么请求的方法就是OPTIONS)或者响应的状态码,其包含元数据、头部区域和数据。

如果数据是通过正常的put或者post方法发送的,那么payload就是一个http请求起始行紧接一个CRLF后面的那一部分。

1
2
3
4
5
起始行: POST /getProduct HTTP/1.1
首部: Content-Type: application/json

主体1:{"productId":3189} # 单参
主体2:{"productId":3189,"orderId":145} # 多参

同样的,我们可以将payload形式的参数通过FormData()来组装。

FormData组装后截图

通过FormData()组装后的数据就像表单数据一样,变成了键/值对的形式。

小结

  • 首部属性contentType可以改变请求的数据提交方式:application/json(payload),application/x-www-form-urlencoded(formData)
  • 服务端的响应方式决定客户端的提交方式
  • 使用FormData()可以通过payload提交表单数据:multipart/form-data