🌓 实现请求和响应配置化
# 需求分析
在 aixos
库中,默认配置会添加 transformRequest
和 transformResponse
两个字段,它们的值是一个数组或者是一个函数。
transformRequest
:允许将请求数据发送到服务器之前进行修改,适用于put
、post
和patch
请求方法,如果值是数组,则数组中的最后一个函数必须返回一个字符串FormData
、URLSearchParams
、Blob
等类型作为xhr.send
方法的参数,而且在transform
过程中可以修改headers
对象;transfromResponse
允许在相应数据传递给then
或者catch
之前对它们进行修改;当值为数组的时候,数组的每个函数都是一个转换函数,前者的输出作为后者的输入。
🌰 例子:
axios({ transfromRequest: [(function(data) { return qs.stringify(data) }), ...axios.defaults.transformRequest], transformResponse: [axios.defaults.transformResponse, function(data) { if(typeof data === 'object') { data.b = 2 } return data }], url: '/config/post', method: 'post', data: { a: 1 } })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 修改默认配置
在 src/types/index.ts
中:
添加一个类型 AxiosTransformer
。
export interface AxiosTransformer {
(data: any, headers?: any):any
}
1
2
3
2
3
然后修改 AxiosRequestConfig
的类型定义:
export interface AxiosRequestConfig {
// ...
transformRequest?: AxiosTransformer | AxiosTransformer[]
transformResponse?: AxiosTransformer | AxiosTransformer[]
}
1
2
3
4
5
2
3
4
5
添加两个可选属性。
然后修改默认配置,在 src/defaults.ts
中:
import { AxiosRequestConfig } from './types'
import { processHeaders } from './helpers/headers'
import { transformRequest, transformResponse } from './helpers/data'
const defaults: AxiosRequestConfig = {
method: 'get',
timeout: 0,
headers: {
common: {
Accept: 'application/json, text/plain, */*'
}
},
transformRequest: [
function(data: any, headers: any): any {
processHeaders(headers, data)
return transformRequest(data)
}
],
transformResponse: [
function(data: any): any {
return transformResponse(data)
}
]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
将之前对请求数据和相应数据的处理逻辑,放到默认配置中。
# transform
逻辑重构
重构之前写的 对请求数据和相应数据的处理逻辑。可能会编写多个转换函数,先定义一个 transform
函数处理这些转换函数的调用逻辑。
src/core/transform.ts
:
import { AxiosTransformer } from '../types'
export default function transform(
data: any,
headers: any,
fns?: AxiosTransformer | AxiosTransformer[]
): any {
if(!fns) return data
if(!Array.isArray(fns)) fns = [fns]
fns.forEach(fn => {
data = fn(data, headers)
})
return data
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
transform
函数中接收三个参数,其中fns
代表一个或者多个转换函数,内部逻辑为 遍历fns
,执行这些转换函数,并且把data
和headers
作为参数传入,每个转换函数返回的data
或作为下一个转换函数的参数data
传入。
修改对请求数据和相应数据处理的逻辑:
src/core/dispatchRequest.ts
:
function processConfig(config: AxiosRequestConfig): void {
config.url = transformURL(config)
config.headers = transformRequestHeader(config)
config.data = transform(config.data, config.headers, config.transformRequest)
config.headers = flattenHeaders(config.headers, config.method!)
}
1
2
3
4
5
6
2
3
4
5
6
function transformResponseData(res: AxiosResponse): AxiosResponse {
res.data = transform(res.data, res.headers, res.config.transformResponse)
return res
}
1
2
3
4
2
3
4
将对请求数据的处理和对响应数据的处理改成适用
transform
函数的实现,并且把配置中的transformRequest
以及transformResponse
分别传入。
# 编写测试 DEMO
axios({
transfromRequest: [(function(data) {
return qs.stringify(data)
}), ...axios.defaults.transformRequest],
transformResponse: [axios.defaults.transformResponse, function(data) {
if(typeof data === 'object') {
data.b = 2
}
return data
}],
url: '/config/post',
method: 'post',
data: {
a: 1
}
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
编辑 (opens new window)
📢 上次更新: 2022/09/02, 10:18:16