qs—對象序列化爲查詢參數和URL解析成對象的庫

安裝

npm install qs

使用

let qs = require('qs')
// 或者 import qs from 'qs'

方法

  • 對象序列化爲URL查詢參數
let obj = {a: 1, b: 2, c: 3};
let str = qs.stringify(obj); // a=1&b=2&c=3
  • URL查詢參數解析爲對象
let str = 'a=1&b=2&c=3';
let obj = qs.parse(obj); // {a: 1, b: 2, c: 3}

常用參數

qs.parse(string, options)

參數名 默認值 說明
plainObjects false 是否通過Object.create(null)方式創建新對象,如果是,則返回的對象不具有Object的原型方法,且可以指定原型對象的屬性值
allowPrototypes false 是否允許指定原型屬性的值
depth 5 qs把字符串解析爲對象時,可以解析URI編碼過的字符,也可以解析嵌套子對象,子對象支持用[]來表示,默認最多支持嵌套5層,該屬性可以修改支持的嵌套層數
parameterLimit 1000 可以解析的參數個數,默認1000個鍵值對,超過的會忽略
ignoreQueryPrefix false 字符串開頭的?是否忽略,默認會解析到第一個參數的key裏
delimiter & 連接字符串的分割符,可以是一個字符串,也可以是正則,滿足的都支持解析 例如: /[;,]/
allowDots false 嵌套子對象的表示方式,是否支持.表示,默認false時,是[]表示
chartset utf-8 編碼格式
decoder function(str){} 自定義解碼方法
comma false 是否支持逗號連接的值轉爲數組, a={b:1},{c:d}的除外
arrayLimit 20 數組最大索引值, 超過的話會按照對象來解析
parseArrays true 是否按照數組規則解析爲數組,如果爲false,則全部按照對象格式解析

qs.stringify(object, [options])

參數名稱 默認值 說明
encode true 默認會對序列化後的字符串進行utf-8編碼
encodeValuesOnly false 是否只對值編碼
encoder function(str){} 自定義編碼方法, encode爲false時無效
indices true 數組的序列化,是否要顯式序列化索引, false: ‘a=b&a=c&a=d’, true: a[0]=b&a[1]=c&a[2]=d
arrayFormat indices/brackets/repeat/comma indices:顯示序列化數組索引;brackets: 只用中括號表示;repeat: 重複可以來表示數組;comma: 數組值用逗號連接
addQueryPrefix false 序列化後的字符串開頭是否自動添加 ?
delimiter ‘&’ 序列化的字符串參數之間的連接符
sort function (a, b){} 序列化時參數排序方法
filter function(key, value){} / [] 只序列化滿足filter的參數

方法參數

1. parse(string, options)


1.1 解析爲對象

  1. qs支持在查詢字符串中創建嵌套對象,方法是通過[]將子建名稱括起來
qs.parse('foo[bar]=baz') // {foo: {bar: 'baz'}}
  1. 支持嵌套多層,默認情況下qs只會解析5層,超過5層的會被作爲一個key
import assert from 'assert'
var expected = {
    a: {
        b: {
            c: {
                d: {
                    e: {
                        f: {
                            '[g][h][i]': 'j'
                        }
                    }
                }
            }
        }
    }
};
var string = 'a[b][c][d][e][f][g][h][i]=j';
assert.deepEqual(qs.parse(string), expected);
  • options
  1. depth
    number 默認 5
    該屬性可以控制qs解析時,允許的嵌套層數
qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 });
// { a: { b: { '[c][d][e][f][g][h][i]': j } }
  1. plainObjects
    boolean, 默認false
    當傳入該參數時,解析後生成的對象是相當於通過Object.create(null)創建的對象,所以需要注意解析後生成的對象,prototype屬性是不存在的,可以給他們設置任意值
qs.parse('a[hasOwnProperty]=b', { plainObjects: true });
// { a: { hasOwnProperty: 'b' } }
  1. allowPrototypes
    boolean, 默認false
    默認情況下,修改Object原型屬性的操作是會被忽略的,如果想保留其他原型屬性,只修改某一個字段,可以使用allowPrototypes屬性來控制,但是要小心使用(如果用到了一個被改寫過的屬性可能會有問題)
qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true });
// { a: { hasOwnProperty: 'b' } }

URI編碼過的字符也可以解析

import assert from 'assert'
assert.deepEqual(qs.parse('a%5Bb%5D=c'), {
    a: { b: 'c' }
});
  1. parameterLimit
    number 默認1000
    qs解析時,默認解析1000個參數,通過該參數可以控制解析的參數個數,超過的會被忽略掉
qs.parse('a=b&c=d', { parameterLimit: 1 });
// { a: b }
  1. ignoreQueryPrefix
    boolean, 默認false
    查詢參數一般以?開頭,默認會被解析到第一個參數的key中,爲了避免把?解析到對象,可以使用該參數控制,從而忽略查詢參數前綴
var protoObject = qs.parse('?a[s]=b&c=3') // { ?a: { s: b }, c: 3}
var protoObject = qs.parse('?a[s]=b&c=3', { ignoreQueryPrefix: true }) // { a: { s: b }, c: 3}
  1. delimiter
    string | regex
    默認qs通過&來分割解析字符串,可以通過delimiter來指定自定義分割符
qs.parse('a=b;c=d', { delimiter: ';' }); // { a: 'b', c: 'd' }

delimiter可以通過正則表達式來制定多個,只要解析過程中遇到制定分割符就進行分割

qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ })// { a: 'b', c: 'd', e: 'f' }
  1. allowDots
    boolean, 默認false
    當字符串中出現 . 的時候,不解析到對象的key中,而是作爲嵌套子對象來處理
var protoObject = qs.parse('?a.s.s.d=b&c=3', { ignoreQueryPrefix: true, allowDots: true })
{ a: { s: { s: { d: 'b' } } }, c:3 }
  1. charset
    編碼格式, 默認utf-8

1.2 解析爲數組

ajax請求中,發送x-www-form-urlencoded格式數據時,如果參數是數組,例如a=[‘b’,‘c’]會被默認解析成a[]=b&a[]=c

  1. qs可以根據[]來解析數組
qs.parse('a[]=b&a[]=c'); // { a: ['b', 'c'] }
  1. 支持指定索引
qs.parse('a[1]=c&a[0]=b');

注意: []裏的值是數字時才能當作數組處理,否則會處理爲對象;當索引不連續時,qs會自動把創建出的稀疏數組壓縮,僅保留有值的順序

  1. 字符串也是值,會保留
qs.parse('a[]=&a[]=c') // { a: ['', 'c'] }

qs.parse('a[0]=b&a[1]=&a[2]=c') // { a: ['b', '', 'c'] }

qs默認數組長度只到20, 所以當指定的索引超過20時,整個屬性會被當作對象處理

  1. 如果指定的索引有數字也有字母的情況下,qs也會按照對象格式來解析
qs.parse('a[0]=b&a[b]=c') // { a: { '0': 'b', b: 'c' } }
  1. qs支持根據,來解析成數組
qs.parse('a=b,c', { comma: true }) // { a: ['b', 'c'] }
  1. 支持解析爲對象數組, 當連續兩個[]中都是數字時,會按照稀疏數組來處理
qs.parse('a[][b]=c') // a: [{ b: 'c' }]
qs.parse('a[][b][0][1]=c') // a: [{ b: ['c'] }] qs認爲0出索引沒有值,當作稀疏數組來處理

  • options
  1. arrayLimit
    number 默認20
    指定允許解析的數組的最大索引
// 索引超過指定的最大值
qs.parse('a[1]=b&a[2]=1', { arrayLimit: 0 }) // { a: { 1: 'b', 2: 1 } }

qs.parse('a[1]=b&a[2]=1', { arrayLimit: 2 }) // { a: ['b', 1] }
  1. parseArrays
    boolean 默認true qs是否支持解析爲數組
// parseArrays 設爲false,不解析爲數組,全部按照對象來解析
qs.parse('a[]=b', { parseArrays: false }); // { a: { '0': 'b' } }
  1. comma
    boolean 默認false,是否支持解析,分割符鏈接的數組,除了這樣的a={b:1},{c:d}
qs.parse('a=b,c', { comma: true })


2. stringify(object, [options])

  1. 對象序列化時,會默認URI編碼後輸出。
assert.equal(qs.stringify({ a: 'b' }), 'a=b');
assert.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c');
  1. 序列化數組參數,默認情況下序列化成以下顯式格式
qs.stringify({ a: ['b', 'c', 'd'] }); // 'a[0]=b&a[1]=c&a[2]=d'
  1. 通過指定options參數的indices屬性爲false可以轉成以下格式
qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false });
// 'a=b&a=c&a=d'
  1. 嵌套的對象,序列化時默認用[]表示
qs.stringify({ a: { b: { c: 'd', e: 'f' } } });
// 'a[b][c]=d&a[b][e]=f'
  1. 空字符串和空對象的序列化結果
// 值爲空字符串時如下
assert.equal(qs.stringify({ a: '' }), 'a=');
// 控對象空數組如下
assert.equal(qs.stringify({ a: [] }), '');
assert.equal(qs.stringify({ a: {} }), '');
assert.equal(qs.stringify({ a: [{}] }), '');
assert.equal(qs.stringify({ a: { b: []} }), '');
assert.equal(qs.stringify({ a: { b: {}} }), '');

值爲null時會當作空字符串處理
值爲undefined時會忽略

  • options
  1. encode
    是否編碼輸出
  2. encodeValuesOnly
    是否只對值進行編碼
  3. encoder
    自定義編碼方法, 當encode爲false時無效
var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) {
    // Passed in values `a`, `b`, `c`
    return // Return encoded string
}})

對應的解碼方法

var decoded = qs.parse('x=z', { decoder: function (str) {
    // Passed in values `x`, `z`
    return // Return decoded string
}})

可以對key, value指定不同的編碼方法

var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str, defaultEncoder, charset, type) {
    if (type === 'key') {
        return // Encoded key
    } else if (type === 'value') {
        return // Encoded value
    }
}})
  1. indices
    是否顯式序列化數組
  2. arrayFormat
    可以通過指定該值來控制數組序列化輸出
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' })
// 重複顯示key 'a=b&a=c'
qs.stringify({ a: ['b', 'c']}, { arrayFormat: 'comma' })
// 用都好連接 'a=b,c'
  1. allowDots
    嵌套的子對象屬性表示方法, true表示用.連接, 否則默認的[]連接
  2. addQueryPrefix
    對象序列化爲查詢字符串時,默認開頭不帶?, 通過設置該屬性爲true,字符串會自動?開頭
  3. delimiter
    指定對象序列化時的連接符
  4. sort
    指定參數key的排序方法
// 按照字母順序排序
function alphabeticalSort(a, b) {
    return a.localeCompare(b);
}
assert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y')
  1. filter
    可以時函數或者數組
    函數時接受(key, value)兩個參數,分別表示參數的鍵, 值
qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2, 'e'], encode: false })
// a[0]=b&a[2]=d&e=f

通過filter數組來篩選需要序列化進查詢字符串的key

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