qs是一個流行的查詢參數序列化和解析庫。可以將一個普通的object序列化成一個查詢字符串,或者反過來將一個查詢字符串解析成一個object,而且支持複雜的嵌套。它上手很容易:
Qs.parse('x[]=1') // {x: ['1']}
Qs.stringify({x: [1]}) // x%5B0%5D=1
qs的兩個方法都接受一個可選的第二參數,可以讓我們對結果進行配置,個人覺得比較有用的有以下幾個:
ignoreQueryPrefix和addQueryPrefix
ignoreQueryPrefix這個參數可以自動幫我們過濾掉location.search前面的❓,然後再解析,addQueryPrefix
設爲true可以在序列化的時候給我們加上?
// 解析
Qs.parse('?x=1') // {?x: "1"}
Qs.parse('?x=1', {ignoreQueryPrefix: true}) // {x: "1"}
// 序列化
Qs.stringify({x: "1"}) // x=1
Qs.parse({x: "1"}, {addQueryPrefix: true}) // ?x=1
數組解析和序列化
數組序列化有幾種方式:indices
, brackets
, repeat
, comma
,用來控制字符串的生成格式。來看下面的例子:
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' })
// 'a[0]=b&a[1]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' })
// 'a[]=b&a[]=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
// 'a=b&a=c'
qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'comma' })
// 'a=b,c'
上面的四種方式,序列化得到的結果越來越精簡,但是當面對嵌套數組時,卻會導致不同程度的信息丟失,而且丟失的越來越嚴重。以四種方式對{ a: [['b'], 'c'] }
stringify 再 parse爲例:
qs.parse(qs.stringify({ a: [['b'], 'c'] }, { arrayFormat: 'indices' })) // { a: [['b'], 'c'] }
qs.parse(qs.stringify({ a: [['b'], 'c'] }, { arrayFormat: 'brackets' })) // {a: ["b", "c"]}
qs.parse(qs.stringify({ a: [['b'], 'c'] }, { arrayFormat: 'repeat' })) // {a: ["b", "c"]}
qs.parse(qs.stringify({ a: [['b'], 'c'] }, { arrayFormat: 'comma' })) // {a: "b,c"}
所以當數據裏有嵌套時最好使用indices
模式,好在這也是默認模式。
delimiter
delimiter可以控制將哪種字符作爲分隔符,由於cookie的格式是使用;
來分隔,一個有用的例子是用來解析cookie:
document.cookie // "_ga=GA1.2.806176131.1570244607; _jsuid=1335121594; _gid=GA1.2.1453554609.1575990858"
Qs.parse(document.cookie, {delimiter:'; '})
數字類型的解析
正如我們在第一個例子看到的那樣,我們把一個數字序列化再還原,得到的並不是一個數字,而是一個字符串:
Qs.parse(Qs.stringify({x:1})) // {x: '1'}
如果希望解析出來依舊是數字,可以參考這個issue,就是寫一個自定義decoder:
Qs.parse('x[0]=1', {
decoder(str, defaultEncoder, charset, type) {
if (/^(\d+|\d*\.\d+)$/.test(str)) {
return parseFloat(str)
}
return str
}
})
本文完