qs庫使用指南

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
    }
  })

本文完

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章