主要内容:对 get 请求参数的处理
需求分析
看下面这个请求
axios({
method: 'get',
url: '/base/get',
params: {
a: 1,
b: 2
}
})
系列一实现了axios
的基本请求,但是如果你细心会发现还存在问题,就是我们的请求url
其实是不全的。具体看下图
图片占位
可以看到我们并没有将params
的参数拼接到url
尾部,so 我们这一节要做的事情就是完善 url。
在axios
中参数params
可以有多重,如下所示
// 为数组
axios({
method: 'get',
url: '/base/get',
params: {
foo: ['aaa', 'bbb']
}
})
// url: /base/get?foo[]=aaa&foo[]=bbb
// 为对象
axios({
method: 'get',
url: '/base/get',
params: {
foo: {
bar: 'baz'
}
}
})
// url: /base/get?foo=%7B%22bar%22:%22baz%22%7D, foo 后面拼接的是 {"bar":"baz"} encode 后的结果
// 为日期
const date = new Date()
axios({
method: 'get',
url: '/base/get',
params: {
date
}
})
// url: /base/get?date=2019-04-01T05:55:39.030Z, date 后面拼接的是 date.toISOString() 的结果
// 特殊字符等。字符:@ : $ , [ ] 是允许出现在url参数中的
axios({
method: 'get',
url: '/base/get',
params: {
foo: '@:$, '
}
})
// url: /base/get?foo=@:$+, 注意,我们会把空格 转换成 +
此章节只展示params
为数组
时的实现,其余的可以自己对照源码进行查看
思路分析
先看下列请求,接下来的代码都是以这个请求为例进行说明。
axios({
method: 'get',
url: '/base/get',
params: {
foo: ['aaa', 'bbb']
}
})
我们最终要的结果为/base/get?foo[]=aaa&foo[]=bbb
,大体实现步骤为以下几步。
- 1、1、创建一个数组,用于存放键值对,其最终结构为[ 'foo[]=aaa', 'foo[]=bbb' ]
- 2、循环params,获取其键值对进行操作
- 3、创建一个临时数组,用于存放处理好的params,结构为[ 'aaa', 'bbb' ]
- 4、4、循环添加,以key=value的形式,
- 5、字符串拼接
实现
接下来我们来看具体实现
demo.js
let url = '/base/get'
let params = {
foo: ['aaa', 'bbb']
}
// 1、创建一个数组,用于存放键值对,其最终结构为[ 'foo[]=aaa', 'foo[]=bbb' ]
const parts = []
// 2、循环params,获取其键值对进行操作
Object.keys(params).forEach(key => {
let val = params[key] // val: ['aaa', 'bbb'] xiaofeng, key:foo too
// 3、创建一个临时数组,用于存放处理好的params,结构为[ 'aaa', 'bbb' ]
let values = []
if (Array.isArray(val)) {
values = val
key += '[]'
} else {
values = [val]
}
// 4、循环添加,以key=value的形式,
values.forEach(item => {
parts.push(`${key}=${item}`)
})
// parts: [ 'foo[]=aaa', 'foo[]=bbb' ]
})
let serializedParams = parts.join('&')
// 5、字符串拼接
url += `${url}?${serializedParams}`
console.log(url) // 输出:/base/get/base/get?foo[]=aaa&foo[]=bbb
这里用原生 js 粗略的实现了这个功能。
接下来我们用typescript
来进行改写
buildURL 函数实现
遵循模块化的思想,我们也将这个功能拆分出来,成为一个单独的模块。 src
下新建一个helpers
目录用于存放工具函数和辅助方法,在这个目录下新建一个url.ts
文件用于存放url
相关的工具函数。
根据上面的代码,你不难写出如下代码
export function buildURL(url: string, params?: any): string {
if (!params) {
return url
}
// 这里的写法可以参考typescript文档https://www.tslang.cn/docs/handbook/basic-types.html
const parts: string[] = []
Object.keys(params).forEach(key => {
const val = params[key]
if (val === null || typeof val === 'undefined') {
return
}
let values = []
if (Array.isArray(val)) {
values = val
key += '[]'
} else {
values = [val]
}
values.forEach(item => {
//
parts.push(`${key}=${item}`)
})
})
let serializedParams = parts.join('&')
url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
return url
}
此时我们就用 typescript 实现了对url
参数为数组时的处理,不过我们这里还有很多需要完善的地方,接下来我带领你一步一步的去完善,修改它。
为完待续...
换工作的原因这个暂时没时间更新了。等忙过这一段时间