qs allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets []. For example, the string 'foo[bar]=baz' converts to:
When using the plainObjects option the parsed value is returned as a null object, created via Object.create(null) and as such you should be aware that prototype methods will not exist on it and a user may set those names to whatever value they like:
By default parameters that would overwrite properties on the object prototype are ignored, if you wish to keep the data from those fields either use plainObjects as mentioned above, or set allowPrototypes to true which will allow user input to overwrite those properties. WARNING It is generally a bad idea to enable this option as it can cause problems when attempting to use the properties that have been overwritten. Always be careful with this option.
You can also nest your objects, like 'foo[bar][baz]=foobarbaz':
assert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), { foo: { bar: { baz:'foobarbaz' } }});
By default, when nesting objects qs will only parse up to 5 children deep. This means if you attempt to parse a string like 'a[b][c][d][e][f][g][h][i]=j' your resulting object will be:
qs can also parse arrays using a similar [] notation:
var withArray =qs.parse('a[]=b&a[]=c');assert.deepEqual(withArray, { a: ['b','c'] });
You may specify an index as well:
var withIndexes =qs.parse('a[1]=c&a[0]=b');assert.deepEqual(withIndexes, { a: ['b','c'] });
Note that the only difference between an index in an array and a key in an object is that the value between the brackets must be a number to create an array. When creating arrays with specific indices, qs will compact a sparse array to only the existing values preserving their order:
var noSparse =qs.parse('a[1]=b&a[15]=c');assert.deepEqual(noSparse, { a: ['b','c'] });
Note that an empty string is also a value, and will be preserved:
qs will also limit specifying indices in an array to a maximum index of 20. Any array members with an index of greater than 20 will instead be converted to an object with the index as the key:
var withMaxIndex =qs.parse('a[100]=b');assert.deepEqual(withMaxIndex, { a: { '100':'b' } });
This limit can be overridden by passing an arrayLimit option:
(Note: the encoder option does not apply if encode is false)
Analogue to the encoder there is a decoder option for parse to override decoding of properties and values:
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.
When arrays are stringified, by default they are given explicit indices:
If you only want to override the serialization of Date objects, you can provide a serializeDate option:
var date =newDate(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) { returnd.getTime(); } }),'a=7');
You may use the sort option to affect the order of parameter keys:
functionalphabeticalSort(a, b) {returna.localeCompare(b);}assert.equal(qs.stringify({ a:'c', z:'y', b :'f' }, { sort: alphabeticalSort }),'a=c&b=f&z=y');
Finally, you can use the filter option to restrict which keys will be included in the stringified output. If you pass a function, it will be called for each key to obtain the replacement value. Otherwise, if you pass an array, it will be used to select properties and array indices for stringification:
By default, null values are treated like empty strings:
var withNull =qs.stringify({ a:null, b:'' });assert.equal(withNull,'a=&b=');
Parsing does not distinguish between parameters with and without equal signs. Both are converted to empty strings.
var equalsInsensitive =qs.parse('a&b=');assert.deepEqual(equalsInsensitive, { a:'', b:'' });
To distinguish between null values and empty strings use the strictNullHandling flag. In the result string the null values have no = sign:
var strictNull =qs.stringify({ a:null, b:'' }, { strictNullHandling:true });assert.equal(strictNull,'a&b=');
To parse values without = back to null use the strictNullHandling flag:
var parsedStrictNull =qs.parse('a&b=', { strictNullHandling:true });assert.deepEqual(parsedStrictNull, { a:null, b:'' });
To completely skip rendering keys with null values, use the skipNulls flag:
var nullsSkipped =qs.stringify({ a:'b', c:null}, { skipNulls:true });assert.equal(nullsSkipped,'a=b');
Dealing with special character sets
By default the encoding and decoding of characters is done in utf-8. If you wish to encode querystrings to a different character set (i.e. Shift JIS) you can use the qs-iconv library:
RFC3986 used as default option and encodes ' ' to %20 which is backward compatible. In the same time, output can be stringified as per RFC1738 with ' ' equal to '+'.
assert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c');
assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c');
assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c');