var encodedValues = qs.stringify( { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, { encodeValuesOnly: true } ); assert.equal(encodedValues,'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h');
可以通过设置encoder 选项自定义编码方式(注意:当 encode 被设置为 false 的时候,不适用):
var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) { // Passed in values `a`, `b`, `c` return // Return encoded string }})
与encoder 类似 decoder 可以用来解码:
var decoded = qs.parse('x=z', { decoder: function (str) { // Passed in values `x`, `z` return // Return decoded string }})
Examples beyond this point will be shown as though the output is not URI encoded for clarity. Please note that the return values in these cases will be URI encoded during real usage.
当数组被序列化时,默认显示索引:
qs.stringify({ a: ['b', 'c', 'd'] }); // 'a[0]=b&a[1]=c&a[2]=d'
可以通过设置 indices 为 false 不显示索引:
qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }); // 'a=b&a=c&a=d'
可以通过设置 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' }) // 'a=b&a=c'
对象序列化时,默认使用 [] 表示法:
qs.stringify({ a: { b: { c: 'd', e: 'f' } } }); // 'a[b][c]=d&a[b][e]=f'
通过设置 allowDots 为 true修改为点表示法:
qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true }); // 'a.b.c=d&a.b.e=f'
空字符串和null值将被省略,但是=会保留:
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: {}} }), '');
值为 undefined 的属性将会被完全忽略:
assert.equal(qs.stringify({ a: null, b: undefined }), 'a=');
addQueryPrefix 设置为 true可以在查询字符串前面加 ?:
assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d');
分隔符也可以设置:
assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d');
如果只是序列化日期对象,可以使用 serializeDate 选项:
var date = new Date(7); assert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A')); assert.equal( qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }), 'a=7' );
可以使用 sort 选项来修改键的顺序:
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');
最后,可以使用 filter 选项过滤序列化输出的键。如果给filter传递一个函数,每个键调用一次该函数并用返回的值替换原来值。如果给filter传递一个数组,它将用于选择对象的key和数组的索引:
function filterFunc(prefix, value) { if (prefix == 'b') { // Return an `undefined` value to omit a property. return; } if (prefix == 'e[f]') { return value.getTime(); } if (prefix == 'e[g][0]') { return value * 2; } return value; } qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc }); // 'a=b&c=d&e[f]=123&e[g][0]=4' qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] }); // 'a=b&e=f' qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] }); // 'a[0]=b&a[2]=d'
处理 null 值
默认情况下,null 值被视为空对象:
var withNull = qs.stringify({ a: null, b: '' }); assert.equal(withNull, 'a=&b=');
解析字符串的时候并不会区分参数有没有等号,没有值的话都会解析为空字符串:
var equalsInsensitive = qs.parse('a&b='); assert.deepEqual(equalsInsensitive, { a: '', b: '' });
要想区分空字符串和null值可以使用 strictNullHandling 选项,序列化后的 null 值没有=
var strictNull = qs.stringify({ a: null, b: '' }, { strictNullHandling: true }); assert.equal(strictNull, 'a&b=');
要解析不带 = 的值返回 null可以使用 strictNullHandling 选项:
var parsedStrictNull = qs.parse('a&b=', { strictNullHandling: true }); assert.deepEqual(parsedStrictNull, { a: null, b: '' });
想要完全跳过值为 null 的键不解析,可以使用 skipNulls 选项:
var nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true }); assert.equal(nullsSkipped, 'a=b');
处理特殊字符集:
默认情况下,字符的编码和解码在utf-8中完成。 如果希望将查询字符串编码为不同的字符集(i.e.Shift JIS),您可以使用qs-iconv库: