我们在与后端接口联调中,你知道请求体可以由哪几种类型,以及对应的 Content-Type 是多少吗?
今天以 Apifox Echo 演示一下不同 Content-Type 的 HTTP 报文。关于 Apifox Echo 可查看我以前的文章:通过 Apifox Echo 学习 curl/httpie 命令。
Content Type
当前端向后端请求 API 接口时,不同类型的 Content-Type 对应不同的请求体(Request Body)。
aplication/json:请求体为 JSONapplication/x-www-form-urlencoded:请求体为以&分割的字符串,如a=3&b=4multipart/form-data:请求体以 Boundary 分割
在使用 curl 时,可以通过参数 --data/-d 配置请求体(Request Body)。
可通过 Apifox Echo 进行测试,如果接收到的是 JSON,则会放置于 json 字段,Form 则会置于 form 字段。
# 使用 Form 发送请求
$ curl -X POST echo.apifox.com/post -H "content-type: application/x-www-form-urlencoded" -d 'a=3&b=4'
{
"args": {},
"data": "",
"files": {},
"form": {
"a": "3",
"b": "4"
},
"headers": {
"Accept": "*/*",
"Content-Length": "3",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "echo.apifox.com",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-63454557-3cd5f9a53682be3a327dd0a3"
},
"json": null,
"url": "http://echo.apifox.com/post"
}
# 使用 JSON 发送请求
$ curl -X POST echo.apifox.com/post -H "content-type: application/json" -d '{"a": 3, "b": 4}'
{
"args": {},
"data": "{\"a\": 3, \"b\": 4}",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Content-Length": "8",
"Content-Type": "application/json",
"Host": "echo.apifox.com",
"User-Agent": "curl/7.79.1",
"X-Amzn-Trace-Id": "Root=1-63454532-1aa1d82138215128077cd85d"
},
"json": {
"a": 3
},
"url": "http://echo.apifox.com/post"
}
另外,在 Apifox 中也可以配置其 Content-Type 以及对应的请求体编码。
fetch API
因此,我们前端通过 fetch API 发送请求,携带 body 时,需要:
- 配置
content-type - 配置为对应
content-type的 data。比如为 JSON 时,需要手动JSON.stringify进行编码,为 Form(即 application/www-form-url-encoded)时,通过 URLSearchParams API 进行编码。
在 fetch API 中,对请求体总是最纯正原始的编码方案,但也更有助于我们理解 HTTP 中的 Content-Body 以及请求体。
可将以下代码输入浏览器控制台进行尝试。
// 对于 application/json 的数据需要手动 JSON.stringify
await fetch('https://echo.apifox.com/post', {
method: 'POST',
body: JSON.stringify({
a: 3,
b: 4
}),
headers: {
'content-type': 'application/json'
}
}).then(res => res.json())
// 对于 application/www-form-url-encoded 的数据也需要手动编码
await fetch('https://echo.apifox.com/post', {
method: 'POST',
body: new URLSearchParams({ a: 3, b: 4}),
headers: {
'content-type': 'application/www-form-url-encoded'
}
}).then(res => res.json())
axios
axios 这种更进一步封装的请求库,将会自动指定 Content-Type 以及对数据进行自动编码。
可将以下代码输入浏览器控制台进行尝试。
const axios = await import('https://cdn.skypack.dev/axios').then(r => r.default)
// 将自动是 JSON 格式,并自动对 object 进行序列化
axios.post('https://echo.apifox.com/post', { a: 3, b: 4 })
关于 axios 更多请查看axios 中的请求体编码。
作业
- 使用 Apifox Echo 测试 json/form,并观察请求体
- 如何对 JSON/Form 数据进行序列化作为 Body 在 fetch API 中发送
- 如何基于
fetch API实现简单的类似axios,使得对请求体简单封装