- 小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
axios中对各种类型参数的处理。
1. 字符串/数字-(错误的)
在官方文档中有这样的一段话
// 必须是一个无格式对象(plain object,对象字面量或使用object.create()创建)或 URLSearchParams 对象 params: { ID: 12345 },
所以我们需要使用对象格式传参。
但是笔者验证过
axios({
baseURL:"http://localhost:4396",
method: 'get',
url: '/api/test/get',
params: 1
})
2. 普通参数
axios({
baseURL:"http://localhost:4396",
method: 'get',
url: '/api/test/get',
params: {
a: 1,
b: 2
}
})
3. URLSearchParams
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get",
params: new URLSearchParams('?a=1')
});
4 数组
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get",
params: {
a: [1, 2],
},
});
5. object -> JSON.stringify
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get",
params: {
a: {
b: "1",
},
},
});
6. date ->toISOString()
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get",
params: {
a:new Date(),
},
});
7. 特殊字符
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get",
params: {
foo: "@:$, []",
},
});
8. null / undefined -> 直接忽略
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get",
params: {
a: "1",
b: null,
},
});
9. 存在hash# -> 去掉hash
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get#hash?a=1",
params: {
b: "2",
},
});
10 url中存在参数
// url 中已存在参数
axios({
baseURL: "http://localhost:4396",
method: "get",
url: "/api/test/get?a=1",
params: {
b: "2",
},
});
实现
- buildURL.ts
import { isDate, isObject,isURLSearchParams } from './../util/index'
function encode(val: string): string {
// 这里的%40 是后面字符的十六进制的转义序列
return encodeURIComponent(val)
.replace(/%40/g, '@')
.replace(/%3A/gi, ':')
.replace(/%24/g, '$')
.replace(/%2C/gi, ',')
.replace(/%20/g, '+')
.replace(/%5B/gi, '[')
.replace(/%5D/gi, ']')
}
export default function buildURL(url: string, params: any): string {
// 如果不存在params参数,直接返回
if (!params) {
return url
}
if(isURLSearchParams(params)){
return url += (url.includes('?') ? '&' : '?') + params.toString()
}
const parts: string[] = []
console.log(params)
// 对所有参数进行遍历
// 例子
// params: {
// a: [1, 2, 3, 34],
// b: {c:1},
// d:new Date()
// },
Object.keys(params).forEach((key: string) => {
const val: any = params[key]
// 如果值是null或者undefined直接跳过
if (val === null || typeof val === 'undefined') {
return
}
let tempVal: string[] = []
// 如果当前参数是数组,例如a
if (Array.isArray(val)) {
tempVal = val
// 数组变成a[]=1&a[]=2&a[]=3&a[]=34,所以要在key后面加上[ ]
key = key + '[]'
} else {
// 如果不是数组变成数组,这里变成数组,是为了共用下面的foreach
// 当然也可以不变成数组,但是下面就要对tempVal的类型进行判断
tempVal = [val]
}
tempVal.forEach((temp: any) => {
if (isDate(temp)) {
temp = val.toISOString();
} else if (isObject(temp)) {
temp = JSON.stringify(temp)
}
// 利用encodeURIComponent变成 URI 格式
parts.push(`${encode(key)}=${encode(temp)}`)
})
})
// 判断url中是否有#
const hashmarkIndex:number = url.indexOf('#');
if (hashmarkIndex !== -1) {
url = url.slice(0, hashmarkIndex);
}
// 判断url有没有已经存在参数 /api/test/get?a=1,如果存在 使用&
url += (url.includes('?') ? '&' : '?') + parts
console.log(url)
return url
}
- 辅助函数 src\util\index.ts
export function isDate(val: any): boolean {
return toString.call(val) === '[object Date]';
}
export function isObject(val: any): boolean {
return val !== null && typeof val === 'object';
}
export function isURLSearchParams(val:any): boolean {
return typeof URLSearchParams !== 'undefined' && val instanceof URLSearchParams;
}