字符串化对象结构库 qs
qs 原作者为 TJ 大神,目前由 ljharb 维护。该库的目的是为了在 URL 中构建清晰的字符串请求数据。
如果是简单的 get 请求我们完全可以这样编写:
export function buildGetQueryString (obj: Record<string, any>) { if (!obj) return '' const nameValuePairs: {name: string; value: string}[] = [] Object.keys(obj).filter(x => obj.hasOwnProperty(x) && obj[x] !== void 0).forEach(name => { nameValuePairs.push({name: name, value: obj[name] === null ? '' : obj[name]}) }) return nameValuePairs.map(x => x.name + '=' + encodeURIComponent(x.value)).join('&')}
// 我们也可以在此处做数据处理
var paramsString = "q=URLUtils.searchParams&topic=api"var searchParams = new URLSearchParams(paramsString);
for (let p of searchParams) { console.log(p);}
如果我们的代码中需要数组,上述代码就没办法解析了。此时我们可以利用正则来解析。
export interface ExtractQueryParamsResult { url: string, params: {[key: string]: string | string[]} | null}
export default function extractQueryParams(url: string): ExtractQueryParamsResult { if (typeof url !== 'string' || !url) { return {url: '', params: null} } const questionIndex: number = url.indexOf('?') let queryString: string = url if (questionIndex >= 0) { queryString = url.substring(questionIndex + 1) url = url.substring(0, questionIndex) }
const params: {[key: string]: string | string[]} = {} const re = /[?&]?([^=]+)=([^&]*)/g let tokens while ((tokens = re.exec(queryString))) { const name: string = decodeURIComponent(tokens[1]) const value: string = decodeURIComponent(tokens[2]) if (params[name] !== undefined) { if (!Array.isArray(params[name])) { params[name] = [params[name] as string] } (params[name] as string[]).push(value) } else { params[name] = value } } return {url, params}}
如此,我们可以使用上述代码来解析 url 中的数组:
const { url, params } = extractQueryParams('abc?bb=1&bb=2&cc=3')
{ url: 'abc', params: { bb: [1, 2], cc: 3 }}
但是当前的代码仍旧无法解析出对象格式代码,所以我们使用 qs 来进行处理
var resultStr = qs.stringify({a: [1,2,3], b: {c: 3}})// a%5B0%5D=1&a%5B1%5D=2&a%5B2%5D=3&b%5Bc%5D=3
var resultObj = qs.parse('a%5B0%5D=1&a%5B1%5D=2&a%5B2%5D=3&b%5Bc%5D=3')// {a: [1,2,3], b: {c: 3}}
// 重点!! qs.parse 可以结构嵌套对象assert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), { foo: { bar: { baz: 'foobarbaz' } }});
通常来说我们如此请求
const queryStr = qs.stringify(options)
// 构建 urlconst url = `${queryUrl}${queryUrl.includes('?') ? '&' : '?'}${queryStr}`
当然,我们还可以用 qs.stringify 来查看缓存函数中的的参数是否发生变化。