# 1. 前言

在上篇文章中,我们处理了发送get请求时携带的参数要拼接在url上,另外,我们知道当发送post请求时,所携带的参数是存在于请求体body中的,那么这篇文章我们就来处理下发送post请求时body里的参数。

# 2. 需求分析

我们通过查阅 mdn (opens new window) 发现: send 方法的参数支持 DocumentBodyInit 类型,BodyInit 包括了 Blob, BufferSource, FormData, URLSearchParams, ReadableStreamUSVString,当没有数据的时候,我们还可以传入 null

但是我们最常用的场景还是传一个普通对象给服务端,例如:

axios({
  method: 'post',
  url: '/api/handleRequestBody/post',
  data: {
    a: 1,
    b: 2
  }
})
1
2
3
4
5
6
7
8

这个时候 data是不能直接传给 send 函数的,我们需要把它转换成 JSON 字符串。

# 3. 实现 transformRequest 函数

根据需求分析,我们要实现一个工具函数,对 request 中的 data 做一层转换。我们在 helpers 目录新建 data.ts 文件。

// src/helpers/data.ts

import {isObject} from './util'

export function transformRequest (data: any): any {
  if (isObject(data)) {
    return JSON.stringify(data)
  }
  return data
}
1
2
3
4
5
6
7
8
9
10

# 4. 利用 transformRequest 函数处理body参数

我们首先定义 transformRequestData函数,去转换请求 body 的数据,内部调用了我们刚刚实现的的 transformRequest 方法。

然后我们在 processConfig 内部添加了这段逻辑,在处理完 url 后接着对 config 中的 data 做处理。

// src/index.ts

import {transformRequest} from "./helpers/data";

function processConfig(config: AxiosRequestConfig): void {
  config.url = transformUrl(config);
  config.data = transformRequestData(config)
}

function transformRequestData(config: AxiosRequestConfig): any {
  const {data} = config
  return transformRequest(data)
}
1
2
3
4
5
6
7
8
9
10
11
12
13

OK,我们对 body 参数处理逻辑就实现完了,接下来我们编写 demo 来试试效果怎么样。

# 5. 编写demo

examples 目录下创建 handleRequestBody目录,在 handleRequestBody目录下创建 index.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>handleRequestBody demo</title>
</head>
<body>
<script src="/__build__/handleRequestBody.js"></script>
</body>
</html>
1
2
3
4
5
6
7
8
9
10

接着再创建 app.ts 作为入口文件:

import axios from '../../src/index'

axios({
  method: 'post',
  url: '/api/handleRequestBody/post',
  data: {
    a: 1,
    b: 2
  }
})
1
2
3
4
5
6
7
8
9
10

接着在 server/server.js 添加新的接口路由:

router.post('/api/handleRequestBody/post', function(req, res) {
  res.json(req.body)
})

1
2
3
4

最后在根目录下的index.html中加上启动该demo的入口:

<li><a href="examples/handleRequestBody">handleRequestBody</a></li>
1

OK,我们在命令行中执行:

# 同时开启客户端和服务端
npm run server | npm start
1
2

接着我们打开 chrome 浏览器,访问 http://localhost:8000/ 即可访问我们的 demo 了,我们点击 handleRequestBody,通过F12network 部分我们可以观察发出的请求以及请求的参数。

# 6. 遗留问题

我们从上图中可以看到,虽然携带的参数已经被正常发出了,但是服务端却返回了一个空对象,感觉服务端好像不能正确解析我们传过去的参数呢,这是什么原因呢?我们下篇文章里继续研究。