需求
实现params参数格式自定义序列化
// params 序列化 - 1axios.get('/more/params', {params: new URLSearchParams('a=1&b=2')}).then(res => {console.log(res)}).catch(err => {console.error(err)})// params 序列化 - 2 默认规则(自己实现),特殊字符保持不变axios.get('/more/params', {params: { c: 3, d: [4, 4, 4, 4] }}).then(res => {console.log(res)}).catch(err => {console.error(err)})// params 序列化 - 3 特殊字符会encodeaxios.get('/more/params', {params: {e: [5, 5, 5, 5],f: 5},paramsSerializer(data) {return qs.stringify(data)}}).then(res => {console.log(res)}).catch(err => {console.error(err)})
代码实现
类型声明
export interface AxiosRequestConfig {
// ...
paramsSerializer?: (params: any) => string
}
修改buildUrl逻辑
export function buildURL(url: string, params?: any, paramsSerializer?: (params: any) => string): string {
if (!params) {
return url
}
let serializedParams = ''
// 传入了 paramsSerializer 优先级最高
if (paramsSerializer) {
serializedParams = paramsSerializer(params)
} else if (isURLSearchParams(params)) {
serializedParams = params.toString()
} else {
const parts: string[] = []
Object.keys(params).forEach(key => {
const value = params[key]
if (value === undefined || value === null) {
return
}
// 统一处理为数组
let values = []
if (Array.isArray(value)) {
key += '[]'
values = value
} else {
values = [value]
}
// 拼接参数
values.forEach(val => {
if (isDate(val)) {
val = (val as Date).toISOString()
}
if (isPlainObject(val)) {
val = JSON.stringify(val as Object)
}
parts.push(`${encode(key)}=${encode(val)}`)
})
})
serializedParams = parts.join('&')
}
if (serializedParams) {
// 去掉锚点# (对于后端没有用)
const markIndex = url.indexOf('#')
if (markIndex !== -1) {
url = url.slice(0, markIndex)
}
// 如果有? 继续拼接&,否则加上?
url += url.indexOf('?') !== -1 ? `&${serializedParams}` : `?${serializedParams}`
}
return url
}
修改transformUrl
function transformUrl(config: AxiosRequestConfig) {
const { url, params, paramsSerializer } = config
return buildURL(url || '', params, paramsSerializer)
}
