@@ -12,13 +12,18 @@ The **qs** module was originally created and maintained by [TJ Holowaychuk](http
12
12
13
13
``` javascript
14
14
var qs = require (' qs' );
15
+ var assert = require (' assert' );
15
16
16
- var obj = qs .parse (' a=c' ); // { a: 'c' }
17
- var str = qs .stringify (obj); // 'a=c'
17
+ var obj = qs .parse (' a=c' );
18
+ assert .deepEqual (obj, { a: ' c' });
19
+
20
+ var str = qs .stringify (obj);
21
+ assert .equal (str, ' a=c' );
18
22
```
19
23
20
24
### Parsing Objects
21
25
26
+ [ ] ( #preventEval )
22
27
``` javascript
23
28
qs .parse (string, [options]);
24
29
```
@@ -27,51 +32,52 @@ qs.parse(string, [options]);
27
32
For example, the string ` 'foo[bar]=baz' ` converts to:
28
33
29
34
``` javascript
30
- {
35
+ assert . deepEqual ( qs . parse ( ' foo[bar]=baz ' ), {
31
36
foo: {
32
37
bar: ' baz'
33
38
}
34
- }
39
+ });
35
40
```
36
41
37
42
When using the ` plainObjects ` option the parsed value is returned as a plain 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:
38
43
39
44
``` javascript
40
- qs .parse (' a. hasOwnProperty=b' , { plainObjects: true });
41
- // { a: { hasOwnProperty: 'b' } }
45
+ var plainObject = qs .parse (' a[ hasOwnProperty] =b' , { plainObjects: true });
46
+ assert . deepEqual (plainObject, { a: { hasOwnProperty: ' b' } });
42
47
```
43
48
44
49
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.
45
50
46
51
``` javascript
47
- qs .parse (' a. hasOwnProperty=b' , { allowPrototypes: true });
48
- // { a: { hasOwnProperty: 'b' } }
52
+ var protoObject = qs .parse (' a[ hasOwnProperty] =b' , { allowPrototypes: true });
53
+ assert . deepEqual (protoObject, { a: { hasOwnProperty: ' b' } });
49
54
```
50
55
51
56
URI encoded strings work too:
52
57
53
58
``` javascript
54
- qs .parse (' a%5Bb%5D=c' );
55
- // { a: { b: 'c' } }
59
+ assert .deepEqual (qs .parse (' a%5Bb%5D=c' ), {
60
+ a: { b: ' c' }
61
+ });
56
62
```
57
63
58
64
You can also nest your objects, like ` 'foo[bar][baz]=foobarbaz' ` :
59
65
60
66
``` javascript
61
- {
67
+ assert . deepEqual ( qs . parse ( ' foo[bar][baz]=foobarbaz ' ), {
62
68
foo: {
63
69
bar: {
64
70
baz: ' foobarbaz'
65
71
}
66
72
}
67
- }
73
+ });
68
74
```
69
75
70
76
By default, when nesting objects ** qs** will only parse up to 5 children deep. This means if you attempt to parse a string like
71
77
` 'a[b][c][d][e][f][g][h][i]=j' ` your resulting object will be:
72
78
73
79
``` javascript
74
- {
80
+ var expected = {
75
81
a: {
76
82
b: {
77
83
c: {
@@ -85,136 +91,138 @@ By default, when nesting objects **qs** will only parse up to 5 children deep. T
85
91
}
86
92
}
87
93
}
88
- }
94
+ };
95
+ var string = ' a[b][c][d][e][f][g][h][i]=j' ;
96
+ assert .deepEqual (qs .parse (string), expected);
89
97
```
90
98
91
99
This depth can be overridden by passing a ` depth ` option to ` qs.parse(string, [options]) ` :
92
100
93
101
``` javascript
94
- qs .parse (' a[b][c][d][e][f][g][h][i]=j' , { depth: 1 });
95
- // { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }
102
+ var deep = qs .parse (' a[b][c][d][e][f][g][h][i]=j' , { depth: 1 });
103
+ assert . deepEqual (deep, { a: { b: { ' [c][d][e][f][g][h][i]' : ' j' } } });
96
104
```
97
105
98
106
The depth limit helps mitigate abuse when ** qs** is used to parse user input, and it is recommended to keep it a reasonably small number.
99
107
100
108
For similar reasons, by default ** qs** will only parse up to 1000 parameters. This can be overridden by passing a ` parameterLimit ` option:
101
109
102
110
``` javascript
103
- qs .parse (' a=b&c=d' , { parameterLimit: 1 });
104
- // { a: 'b' }
111
+ var limited = qs .parse (' a=b&c=d' , { parameterLimit: 1 });
112
+ assert . deepEqual (limited, { a: ' b' });
105
113
```
106
114
107
115
An optional delimiter can also be passed:
108
116
109
117
``` javascript
110
- qs .parse (' a=b;c=d' , { delimiter: ' ;' });
111
- // { a: 'b', c: 'd' }
118
+ var delimited = qs .parse (' a=b;c=d' , { delimiter: ' ;' });
119
+ assert . deepEqual (delimited, { a: ' b' , c: ' d' });
112
120
```
113
121
114
122
Delimiters can be a regular expression too:
115
123
116
124
``` javascript
117
- qs .parse (' a=b;c=d,e=f' , { delimiter: / [;,] / });
118
- // { a: 'b', c: 'd', e: 'f' }
125
+ var regexed = qs .parse (' a=b;c=d,e=f' , { delimiter: / [;,] / });
126
+ assert . deepEqual (regexed, { a: ' b' , c: ' d' , e: ' f' });
119
127
```
120
128
121
129
Option ` allowDots ` can be used to enable dot notation:
122
130
123
131
``` javascript
124
- qs .parse (' a.b=c' , { allowDots: true });
125
- // { a: { b: 'c' } }
132
+ var withDots = qs .parse (' a.b=c' , { allowDots: true });
133
+ assert . deepEqual (withDots, { a: { b: ' c' } });
126
134
```
127
135
128
136
### Parsing Arrays
129
137
130
138
** qs** can also parse arrays using a similar ` [] ` notation:
131
139
132
140
``` javascript
133
- qs .parse (' a[]=b&a[]=c' );
134
- // { a: ['b', 'c'] }
141
+ var withArray = qs .parse (' a[]=b&a[]=c' );
142
+ assert . deepEqual (withArray, { a: [' b' , ' c' ] });
135
143
```
136
144
137
145
You may specify an index as well:
138
146
139
147
``` javascript
140
- qs .parse (' a[1]=c&a[0]=b' );
141
- // { a: ['b', 'c'] }
148
+ var withIndexes = qs .parse (' a[1]=c&a[0]=b' );
149
+ assert . deepEqual (withIndexes, { a: [' b' , ' c' ] });
142
150
```
143
151
144
152
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
145
153
to create an array. When creating arrays with specific indices, ** qs** will compact a sparse array to only the existing values preserving
146
154
their order:
147
155
148
156
``` javascript
149
- qs .parse (' a[1]=b&a[15]=c' );
150
- // { a: ['b', 'c'] }
157
+ var noSparse = qs .parse (' a[1]=b&a[15]=c' );
158
+ assert . deepEqual (noSparse, { a: [' b' , ' c' ] });
151
159
```
152
160
153
161
Note that an empty string is also a value, and will be preserved:
154
162
155
163
``` javascript
156
- qs .parse (' a[]=&a[]=b' );
157
- // { a: ['', 'b'] }
158
- qs .parse (' a[0]=b&a[1]=&a[2]=c' );
159
- // { a: ['b', '', 'c'] }
164
+ var withEmptyString = qs .parse (' a[]=&a[]=b' );
165
+ assert .deepEqual (withEmptyString, { a: [' ' , ' b' ] });
166
+
167
+ var withIndexedEmptyString = qs .parse (' a[0]=b&a[1]=&a[2]=c' );
168
+ assert .deepEqual (withIndexedEmptyString, { a: [' b' , ' ' , ' c' ] });
160
169
```
161
170
162
171
** 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
163
172
instead be converted to an object with the index as the key:
164
173
165
174
``` javascript
166
- qs .parse (' a[100]=b' );
167
- // { a: { '100': 'b' } }
175
+ var withMaxIndex = qs .parse (' a[100]=b' );
176
+ assert . deepEqual (withMaxIndex, { a: { ' 100' : ' b' } });
168
177
```
169
178
170
179
This limit can be overridden by passing an ` arrayLimit ` option:
171
180
172
181
``` javascript
173
- qs .parse (' a[1]=b' , { arrayLimit: 0 });
174
- // { a: { '1': 'b' } }
182
+ var withArrayLimit = qs .parse (' a[1]=b' , { arrayLimit: 0 });
183
+ assert . deepEqual (withArrayLimit, { a: { ' 1' : ' b' } });
175
184
```
176
185
177
186
To disable array parsing entirely, set ` parseArrays ` to ` false ` .
178
187
179
188
``` javascript
180
- qs .parse (' a[]=b' , { parseArrays: false });
181
- // { a: { '0': 'b' } }
189
+ var noParsingArrays = qs .parse (' a[]=b' , { parseArrays: false });
190
+ assert . deepEqual (noParsingArrays, { a: { ' 0' : ' b' } });
182
191
```
183
192
184
193
If you mix notations, ** qs** will merge the two items into an object:
185
194
186
195
``` javascript
187
- qs .parse (' a[0]=b&a[b]=c' );
188
- // { a: { '0': 'b', b: 'c' } }
196
+ var mixedNotation = qs .parse (' a[0]=b&a[b]=c' );
197
+ assert . deepEqual (mixedNotation, { a: { ' 0' : ' b' , b: ' c' } });
189
198
```
190
199
191
200
You can also create arrays of objects:
192
201
193
202
``` javascript
194
- qs .parse (' a[][b]=c' );
195
- // { a: [{ b: 'c' }] }
203
+ var arraysOfObjects = qs .parse (' a[][b]=c' );
204
+ assert . deepEqual (arraysOfObjects, { a: [{ b: ' c' }] });
196
205
```
197
206
198
207
### Stringifying
199
208
209
+ [ ] ( #preventEval )
200
210
``` javascript
201
211
qs .stringify (object, [options]);
202
212
```
203
213
204
214
When stringifying, ** qs** by default URI encodes output. Objects are stringified as you would expect:
205
215
206
216
``` javascript
207
- qs .stringify ({ a: ' b' });
208
- // 'a=b'
209
- qs .stringify ({ a: { b: ' c' } });
210
- // 'a%5Bb%5D=c'
217
+ assert .equal (qs .stringify ({ a: ' b' }), ' a=b' );
218
+ assert .equal (qs .stringify ({ a: { b: ' c' } }), ' a%5Bb%5D=c' );
211
219
```
212
220
213
221
This encoding can be disabled by setting the ` encode ` option to ` false ` :
214
222
215
223
``` javascript
216
- qs .stringify ({ a: { b: ' c' } }, { encode: false });
217
- // 'a[b]=c'
224
+ var unencoded = qs .stringify ({ a: { b: ' c' } }, { encode: false });
225
+ assert . equal (unencoded, ' a[b]=c' );
218
226
```
219
227
220
228
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.
@@ -247,22 +255,19 @@ qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' })
247
255
Empty strings and null values will omit the value, but the equals sign (=) remains in place:
248
256
249
257
``` javascript
250
- qs .stringify ({ a: ' ' });
251
- // 'a='
258
+ assert .equal (qs .stringify ({ a: ' ' }), ' a=' );
252
259
```
253
260
254
261
Properties that are set to ` undefined ` will be omitted entirely:
255
262
256
263
``` javascript
257
- qs .stringify ({ a: null , b: undefined });
258
- // 'a='
264
+ assert .equal (qs .stringify ({ a: null , b: undefined }), ' a=' );
259
265
```
260
266
261
267
The delimiter may be overridden with stringify as well:
262
268
263
269
``` javascript
264
- qs .stringify ({ a: ' b' , c: ' d' }, { delimiter: ' ;' });
265
- // 'a=b;c=d'
270
+ assert .equal (qs .stringify ({ a: ' b' , c: ' d' }, { delimiter: ' ;' }), ' a=b;c=d' );
266
271
```
267
272
268
273
Finally, you can use the ` filter ` option to restrict which keys will be included in the stringified output.
@@ -283,11 +288,11 @@ function filterFunc(prefix, value) {
283
288
}
284
289
return value;
285
290
}
286
- qs .stringify ({ a: ' b' , c: ' d' , e: { f: new Date (123 ), g: [2 ] } }, { filter: filterFunc })
291
+ qs .stringify ({ a: ' b' , c: ' d' , e: { f: new Date (123 ), g: [2 ] } }, { filter: filterFunc });
287
292
// 'a=b&c=d&e[f]=123&e[g][0]=4'
288
- qs .stringify ({ a: ' b' , c: ' d' , e: ' f' }, { filter: [' a' , ' e' ] })
293
+ qs .stringify ({ a: ' b' , c: ' d' , e: ' f' }, { filter: [' a' , ' e' ] });
289
294
// 'a=b&e=f'
290
- qs .stringify ({ a: [' b' , ' c' , ' d' ], e: ' f' }, { filter: [' a' , 0 , 2 ] })
295
+ qs .stringify ({ a: [' b' , ' c' , ' d' ], e: ' f' }, { filter: [' a' , 0 , 2 ] });
291
296
// 'a[0]=b&a[2]=d'
292
297
```
293
298
@@ -296,36 +301,35 @@ qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] })
296
301
By default, ` null ` values are treated like empty strings:
297
302
298
303
``` javascript
299
- qs .stringify ({ a: null , b: ' ' });
300
- // 'a=&b='
304
+ var withNull = qs .stringify ({ a: null , b: ' ' });
305
+ assert . equal (withNull, ' a=&b=' );
301
306
```
302
307
303
308
Parsing does not distinguish between parameters with and without equal signs. Both are converted to empty strings.
304
309
305
310
``` javascript
306
- qs .parse (' a&b=' )
307
- // { a: '', b: '' }
311
+ var equalsInsensitive = qs .parse (' a&b=' );
312
+ assert . deepEqual (equalsInsensitive, { a: ' ' , b: ' ' });
308
313
```
309
314
310
315
To distinguish between ` null ` values and empty strings use the ` strictNullHandling ` flag. In the result string the ` null `
311
316
values have no ` = ` sign:
312
317
313
318
``` javascript
314
- qs .stringify ({ a: null , b: ' ' }, { strictNullHandling: true });
315
- // 'a&b='
319
+ var strictNull = qs .stringify ({ a: null , b: ' ' }, { strictNullHandling: true });
320
+ assert . equal (strictNull, ' a&b=' );
316
321
```
317
322
318
323
To parse values without ` = ` back to ` null ` use the ` strictNullHandling ` flag:
319
324
320
325
``` javascript
321
- qs .parse (' a&b=' , { strictNullHandling: true });
322
- // { a: null, b: '' }
323
-
326
+ var parsedStrictNull = qs .parse (' a&b=' , { strictNullHandling: true });
327
+ assert .deepEqual (parsedStrictNull, { a: null , b: ' ' });
324
328
```
325
329
326
330
To completely skip rendering keys with ` null ` values, use the ` skipNulls ` flag:
327
331
328
332
``` javascript
329
- qs .stringify ({ a: ' b' , c: null }, { skipNulls: true })
330
- // 'a=b'
333
+ var nullsSkipped = qs .stringify ({ a: ' b' , c: null }, { skipNulls: true });
334
+ assert . equal (nullsSkipped, ' a=b' );
331
335
```
0 commit comments