root / HServer / 00.Server / 00.Program / node_modules / qs / README.md
이력 | 보기 | 이력해설 | 다운로드 (14.3 KB)
1 | 39 | HKM | # qs <sup>[![Version Badge][2]][1]</sup> |
---|---|---|---|
2 | |||
3 | [![Build Status][3]][4] |
||
4 | [![dependency status][5]][6] |
||
5 | [![dev dependency status][7]][8] |
||
6 | [![License][license-image]][license-url] |
||
7 | [![Downloads][downloads-image]][downloads-url] |
||
8 | |||
9 | [![npm badge][11]][1] |
||
10 | |||
11 | A querystring parsing and stringifying library with some added security. |
||
12 | |||
13 | Lead Maintainer: [Jordan Harband](https://github.com/ljharb) |
||
14 | |||
15 | The **qs** module was originally created and maintained by [TJ Holowaychuk](https://github.com/visionmedia/node-querystring). |
||
16 | |||
17 | ## Usage |
||
18 | |||
19 | ```javascript |
||
20 | var qs = require('qs'); |
||
21 | var assert = require('assert'); |
||
22 | |||
23 | var obj = qs.parse('a=c'); |
||
24 | assert.deepEqual(obj, { a: 'c' }); |
||
25 | |||
26 | var str = qs.stringify(obj); |
||
27 | assert.equal(str, 'a=c'); |
||
28 | ``` |
||
29 | |||
30 | ### Parsing Objects |
||
31 | |||
32 | [](#preventEval) |
||
33 | ```javascript |
||
34 | qs.parse(string, [options]); |
||
35 | ``` |
||
36 | |||
37 | **qs** allows you to create nested objects within your query strings, by surrounding the name of sub-keys with square brackets `[]`. |
||
38 | For example, the string `'foo[bar]=baz'` converts to: |
||
39 | |||
40 | ```javascript |
||
41 | assert.deepEqual(qs.parse('foo[bar]=baz'), { |
||
42 | foo: { |
||
43 | bar: 'baz' |
||
44 | } |
||
45 | }); |
||
46 | ``` |
||
47 | |||
48 | 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: |
||
49 | |||
50 | ```javascript |
||
51 | var nullObject = qs.parse('a[hasOwnProperty]=b', { plainObjects: true }); |
||
52 | assert.deepEqual(nullObject, { a: { hasOwnProperty: 'b' } }); |
||
53 | ``` |
||
54 | |||
55 | 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. |
||
56 | |||
57 | ```javascript |
||
58 | var protoObject = qs.parse('a[hasOwnProperty]=b', { allowPrototypes: true }); |
||
59 | assert.deepEqual(protoObject, { a: { hasOwnProperty: 'b' } }); |
||
60 | ``` |
||
61 | |||
62 | URI encoded strings work too: |
||
63 | |||
64 | ```javascript |
||
65 | assert.deepEqual(qs.parse('a%5Bb%5D=c'), { |
||
66 | a: { b: 'c' } |
||
67 | }); |
||
68 | ``` |
||
69 | |||
70 | You can also nest your objects, like `'foo[bar][baz]=foobarbaz'`: |
||
71 | |||
72 | ```javascript |
||
73 | assert.deepEqual(qs.parse('foo[bar][baz]=foobarbaz'), { |
||
74 | foo: { |
||
75 | bar: { |
||
76 | baz: 'foobarbaz' |
||
77 | } |
||
78 | } |
||
79 | }); |
||
80 | ``` |
||
81 | |||
82 | By default, when nesting objects **qs** will only parse up to 5 children deep. This means if you attempt to parse a string like |
||
83 | `'a[b][c][d][e][f][g][h][i]=j'` your resulting object will be: |
||
84 | |||
85 | ```javascript |
||
86 | var expected = { |
||
87 | a: { |
||
88 | b: { |
||
89 | c: { |
||
90 | d: { |
||
91 | e: { |
||
92 | f: { |
||
93 | '[g][h][i]': 'j' |
||
94 | } |
||
95 | } |
||
96 | } |
||
97 | } |
||
98 | } |
||
99 | } |
||
100 | }; |
||
101 | var string = 'a[b][c][d][e][f][g][h][i]=j'; |
||
102 | assert.deepEqual(qs.parse(string), expected); |
||
103 | ``` |
||
104 | |||
105 | This depth can be overridden by passing a `depth` option to `qs.parse(string, [options])`: |
||
106 | |||
107 | ```javascript |
||
108 | var deep = qs.parse('a[b][c][d][e][f][g][h][i]=j', { depth: 1 }); |
||
109 | assert.deepEqual(deep, { a: { b: { '[c][d][e][f][g][h][i]': 'j' } } }); |
||
110 | ``` |
||
111 | |||
112 | 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. |
||
113 | |||
114 | For similar reasons, by default **qs** will only parse up to 1000 parameters. This can be overridden by passing a `parameterLimit` option: |
||
115 | |||
116 | ```javascript |
||
117 | var limited = qs.parse('a=b&c=d', { parameterLimit: 1 }); |
||
118 | assert.deepEqual(limited, { a: 'b' }); |
||
119 | ``` |
||
120 | |||
121 | To bypass the leading question mark, use `ignoreQueryPrefix`: |
||
122 | |||
123 | ```javascript |
||
124 | var prefixed = qs.parse('?a=b&c=d', { ignoreQueryPrefix: true }); |
||
125 | assert.deepEqual(prefixed, { a: 'b', c: 'd' }); |
||
126 | ``` |
||
127 | |||
128 | An optional delimiter can also be passed: |
||
129 | |||
130 | ```javascript |
||
131 | var delimited = qs.parse('a=b;c=d', { delimiter: ';' }); |
||
132 | assert.deepEqual(delimited, { a: 'b', c: 'd' }); |
||
133 | ``` |
||
134 | |||
135 | Delimiters can be a regular expression too: |
||
136 | |||
137 | ```javascript |
||
138 | var regexed = qs.parse('a=b;c=d,e=f', { delimiter: /[;,]/ }); |
||
139 | assert.deepEqual(regexed, { a: 'b', c: 'd', e: 'f' }); |
||
140 | ``` |
||
141 | |||
142 | Option `allowDots` can be used to enable dot notation: |
||
143 | |||
144 | ```javascript |
||
145 | var withDots = qs.parse('a.b=c', { allowDots: true }); |
||
146 | assert.deepEqual(withDots, { a: { b: 'c' } }); |
||
147 | ``` |
||
148 | |||
149 | ### Parsing Arrays |
||
150 | |||
151 | **qs** can also parse arrays using a similar `[]` notation: |
||
152 | |||
153 | ```javascript |
||
154 | var withArray = qs.parse('a[]=b&a[]=c'); |
||
155 | assert.deepEqual(withArray, { a: ['b', 'c'] }); |
||
156 | ``` |
||
157 | |||
158 | You may specify an index as well: |
||
159 | |||
160 | ```javascript |
||
161 | var withIndexes = qs.parse('a[1]=c&a[0]=b'); |
||
162 | assert.deepEqual(withIndexes, { a: ['b', 'c'] }); |
||
163 | ``` |
||
164 | |||
165 | 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 |
||
166 | to create an array. When creating arrays with specific indices, **qs** will compact a sparse array to only the existing values preserving |
||
167 | their order: |
||
168 | |||
169 | ```javascript |
||
170 | var noSparse = qs.parse('a[1]=b&a[15]=c'); |
||
171 | assert.deepEqual(noSparse, { a: ['b', 'c'] }); |
||
172 | ``` |
||
173 | |||
174 | Note that an empty string is also a value, and will be preserved: |
||
175 | |||
176 | ```javascript |
||
177 | var withEmptyString = qs.parse('a[]=&a[]=b'); |
||
178 | assert.deepEqual(withEmptyString, { a: ['', 'b'] }); |
||
179 | |||
180 | var withIndexedEmptyString = qs.parse('a[0]=b&a[1]=&a[2]=c'); |
||
181 | assert.deepEqual(withIndexedEmptyString, { a: ['b', '', 'c'] }); |
||
182 | ``` |
||
183 | |||
184 | **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 |
||
185 | instead be converted to an object with the index as the key: |
||
186 | |||
187 | ```javascript |
||
188 | var withMaxIndex = qs.parse('a[100]=b'); |
||
189 | assert.deepEqual(withMaxIndex, { a: { '100': 'b' } }); |
||
190 | ``` |
||
191 | |||
192 | This limit can be overridden by passing an `arrayLimit` option: |
||
193 | |||
194 | ```javascript |
||
195 | var withArrayLimit = qs.parse('a[1]=b', { arrayLimit: 0 }); |
||
196 | assert.deepEqual(withArrayLimit, { a: { '1': 'b' } }); |
||
197 | ``` |
||
198 | |||
199 | To disable array parsing entirely, set `parseArrays` to `false`. |
||
200 | |||
201 | ```javascript |
||
202 | var noParsingArrays = qs.parse('a[]=b', { parseArrays: false }); |
||
203 | assert.deepEqual(noParsingArrays, { a: { '0': 'b' } }); |
||
204 | ``` |
||
205 | |||
206 | If you mix notations, **qs** will merge the two items into an object: |
||
207 | |||
208 | ```javascript |
||
209 | var mixedNotation = qs.parse('a[0]=b&a[b]=c'); |
||
210 | assert.deepEqual(mixedNotation, { a: { '0': 'b', b: 'c' } }); |
||
211 | ``` |
||
212 | |||
213 | You can also create arrays of objects: |
||
214 | |||
215 | ```javascript |
||
216 | var arraysOfObjects = qs.parse('a[][b]=c'); |
||
217 | assert.deepEqual(arraysOfObjects, { a: [{ b: 'c' }] }); |
||
218 | ``` |
||
219 | |||
220 | ### Stringifying |
||
221 | |||
222 | [](#preventEval) |
||
223 | ```javascript |
||
224 | qs.stringify(object, [options]); |
||
225 | ``` |
||
226 | |||
227 | When stringifying, **qs** by default URI encodes output. Objects are stringified as you would expect: |
||
228 | |||
229 | ```javascript |
||
230 | assert.equal(qs.stringify({ a: 'b' }), 'a=b'); |
||
231 | assert.equal(qs.stringify({ a: { b: 'c' } }), 'a%5Bb%5D=c'); |
||
232 | ``` |
||
233 | |||
234 | This encoding can be disabled by setting the `encode` option to `false`: |
||
235 | |||
236 | ```javascript |
||
237 | var unencoded = qs.stringify({ a: { b: 'c' } }, { encode: false }); |
||
238 | assert.equal(unencoded, 'a[b]=c'); |
||
239 | ``` |
||
240 | |||
241 | Encoding can be disabled for keys by setting the `encodeValuesOnly` option to `true`: |
||
242 | ```javascript |
||
243 | var encodedValues = qs.stringify( |
||
244 | { a: 'b', c: ['d', 'e=f'], f: [['g'], ['h']] }, |
||
245 | { encodeValuesOnly: true } |
||
246 | ); |
||
247 | assert.equal(encodedValues,'a=b&c[0]=d&c[1]=e%3Df&f[0][0]=g&f[1][0]=h'); |
||
248 | ``` |
||
249 | |||
250 | This encoding can also be replaced by a custom encoding method set as `encoder` option: |
||
251 | |||
252 | ```javascript |
||
253 | var encoded = qs.stringify({ a: { b: 'c' } }, { encoder: function (str) { |
||
254 | // Passed in values `a`, `b`, `c` |
||
255 | return // Return encoded string |
||
256 | }}) |
||
257 | ``` |
||
258 | |||
259 | _(Note: the `encoder` option does not apply if `encode` is `false`)_ |
||
260 | |||
261 | Analogue to the `encoder` there is a `decoder` option for `parse` to override decoding of properties and values: |
||
262 | |||
263 | ```javascript |
||
264 | var decoded = qs.parse('x=z', { decoder: function (str) { |
||
265 | // Passed in values `x`, `z` |
||
266 | return // Return decoded string |
||
267 | }}) |
||
268 | ``` |
||
269 | |||
270 | 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. |
||
271 | |||
272 | When arrays are stringified, by default they are given explicit indices: |
||
273 | |||
274 | ```javascript |
||
275 | qs.stringify({ a: ['b', 'c', 'd'] }); |
||
276 | // 'a[0]=b&a[1]=c&a[2]=d' |
||
277 | ``` |
||
278 | |||
279 | You may override this by setting the `indices` option to `false`: |
||
280 | |||
281 | ```javascript |
||
282 | qs.stringify({ a: ['b', 'c', 'd'] }, { indices: false }); |
||
283 | // 'a=b&a=c&a=d' |
||
284 | ``` |
||
285 | |||
286 | You may use the `arrayFormat` option to specify the format of the output array: |
||
287 | |||
288 | ```javascript |
||
289 | qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'indices' }) |
||
290 | // 'a[0]=b&a[1]=c' |
||
291 | qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'brackets' }) |
||
292 | // 'a[]=b&a[]=c' |
||
293 | qs.stringify({ a: ['b', 'c'] }, { arrayFormat: 'repeat' }) |
||
294 | // 'a=b&a=c' |
||
295 | ``` |
||
296 | |||
297 | When objects are stringified, by default they use bracket notation: |
||
298 | |||
299 | ```javascript |
||
300 | qs.stringify({ a: { b: { c: 'd', e: 'f' } } }); |
||
301 | // 'a[b][c]=d&a[b][e]=f' |
||
302 | ``` |
||
303 | |||
304 | You may override this to use dot notation by setting the `allowDots` option to `true`: |
||
305 | |||
306 | ```javascript |
||
307 | qs.stringify({ a: { b: { c: 'd', e: 'f' } } }, { allowDots: true }); |
||
308 | // 'a.b.c=d&a.b.e=f' |
||
309 | ``` |
||
310 | |||
311 | Empty strings and null values will omit the value, but the equals sign (=) remains in place: |
||
312 | |||
313 | ```javascript |
||
314 | assert.equal(qs.stringify({ a: '' }), 'a='); |
||
315 | ``` |
||
316 | |||
317 | Key with no values (such as an empty object or array) will return nothing: |
||
318 | |||
319 | ```javascript |
||
320 | assert.equal(qs.stringify({ a: [] }), ''); |
||
321 | assert.equal(qs.stringify({ a: {} }), ''); |
||
322 | assert.equal(qs.stringify({ a: [{}] }), ''); |
||
323 | assert.equal(qs.stringify({ a: { b: []} }), ''); |
||
324 | assert.equal(qs.stringify({ a: { b: {}} }), ''); |
||
325 | ``` |
||
326 | |||
327 | Properties that are set to `undefined` will be omitted entirely: |
||
328 | |||
329 | ```javascript |
||
330 | assert.equal(qs.stringify({ a: null, b: undefined }), 'a='); |
||
331 | ``` |
||
332 | |||
333 | The query string may optionally be prepended with a question mark: |
||
334 | |||
335 | ```javascript |
||
336 | assert.equal(qs.stringify({ a: 'b', c: 'd' }, { addQueryPrefix: true }), '?a=b&c=d'); |
||
337 | ``` |
||
338 | |||
339 | The delimiter may be overridden with stringify as well: |
||
340 | |||
341 | ```javascript |
||
342 | assert.equal(qs.stringify({ a: 'b', c: 'd' }, { delimiter: ';' }), 'a=b;c=d'); |
||
343 | ``` |
||
344 | |||
345 | If you only want to override the serialization of `Date` objects, you can provide a `serializeDate` option: |
||
346 | |||
347 | ```javascript |
||
348 | var date = new Date(7); |
||
349 | assert.equal(qs.stringify({ a: date }), 'a=1970-01-01T00:00:00.007Z'.replace(/:/g, '%3A')); |
||
350 | assert.equal( |
||
351 | qs.stringify({ a: date }, { serializeDate: function (d) { return d.getTime(); } }), |
||
352 | 'a=7' |
||
353 | ); |
||
354 | ``` |
||
355 | |||
356 | You may use the `sort` option to affect the order of parameter keys: |
||
357 | |||
358 | ```javascript |
||
359 | function alphabeticalSort(a, b) { |
||
360 | return a.localeCompare(b); |
||
361 | } |
||
362 | assert.equal(qs.stringify({ a: 'c', z: 'y', b : 'f' }, { sort: alphabeticalSort }), 'a=c&b=f&z=y'); |
||
363 | ``` |
||
364 | |||
365 | Finally, you can use the `filter` option to restrict which keys will be included in the stringified output. |
||
366 | If you pass a function, it will be called for each key to obtain the replacement value. Otherwise, if you |
||
367 | pass an array, it will be used to select properties and array indices for stringification: |
||
368 | |||
369 | ```javascript |
||
370 | function filterFunc(prefix, value) { |
||
371 | if (prefix == 'b') { |
||
372 | // Return an `undefined` value to omit a property. |
||
373 | return; |
||
374 | } |
||
375 | if (prefix == 'e[f]') { |
||
376 | return value.getTime(); |
||
377 | } |
||
378 | if (prefix == 'e[g][0]') { |
||
379 | return value * 2; |
||
380 | } |
||
381 | return value; |
||
382 | } |
||
383 | qs.stringify({ a: 'b', c: 'd', e: { f: new Date(123), g: [2] } }, { filter: filterFunc }); |
||
384 | // 'a=b&c=d&e[f]=123&e[g][0]=4' |
||
385 | qs.stringify({ a: 'b', c: 'd', e: 'f' }, { filter: ['a', 'e'] }); |
||
386 | // 'a=b&e=f' |
||
387 | qs.stringify({ a: ['b', 'c', 'd'], e: 'f' }, { filter: ['a', 0, 2] }); |
||
388 | // 'a[0]=b&a[2]=d' |
||
389 | ``` |
||
390 | |||
391 | ### Handling of `null` values |
||
392 | |||
393 | By default, `null` values are treated like empty strings: |
||
394 | |||
395 | ```javascript |
||
396 | var withNull = qs.stringify({ a: null, b: '' }); |
||
397 | assert.equal(withNull, 'a=&b='); |
||
398 | ``` |
||
399 | |||
400 | Parsing does not distinguish between parameters with and without equal signs. Both are converted to empty strings. |
||
401 | |||
402 | ```javascript |
||
403 | var equalsInsensitive = qs.parse('a&b='); |
||
404 | assert.deepEqual(equalsInsensitive, { a: '', b: '' }); |
||
405 | ``` |
||
406 | |||
407 | To distinguish between `null` values and empty strings use the `strictNullHandling` flag. In the result string the `null` |
||
408 | values have no `=` sign: |
||
409 | |||
410 | ```javascript |
||
411 | var strictNull = qs.stringify({ a: null, b: '' }, { strictNullHandling: true }); |
||
412 | assert.equal(strictNull, 'a&b='); |
||
413 | ``` |
||
414 | |||
415 | To parse values without `=` back to `null` use the `strictNullHandling` flag: |
||
416 | |||
417 | ```javascript |
||
418 | var parsedStrictNull = qs.parse('a&b=', { strictNullHandling: true }); |
||
419 | assert.deepEqual(parsedStrictNull, { a: null, b: '' }); |
||
420 | ``` |
||
421 | |||
422 | To completely skip rendering keys with `null` values, use the `skipNulls` flag: |
||
423 | |||
424 | ```javascript |
||
425 | var nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true }); |
||
426 | assert.equal(nullsSkipped, 'a=b'); |
||
427 | ``` |
||
428 | |||
429 | ### Dealing with special character sets |
||
430 | |||
431 | By default the encoding and decoding of characters is done in `utf-8`. If you |
||
432 | wish to encode querystrings to a different character set (i.e. |
||
433 | [Shift JIS](https://en.wikipedia.org/wiki/Shift_JIS)) you can use the |
||
434 | [`qs-iconv`](https://github.com/martinheidegger/qs-iconv) library: |
||
435 | |||
436 | ```javascript |
||
437 | var encoder = require('qs-iconv/encoder')('shift_jis'); |
||
438 | var shiftJISEncoded = qs.stringify({ a: 'こんにちは!' }, { encoder: encoder }); |
||
439 | assert.equal(shiftJISEncoded, 'a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I'); |
||
440 | ``` |
||
441 | |||
442 | This also works for decoding of query strings: |
||
443 | |||
444 | ```javascript |
||
445 | var decoder = require('qs-iconv/decoder')('shift_jis'); |
||
446 | var obj = qs.parse('a=%82%B1%82%F1%82%C9%82%BF%82%CD%81I', { decoder: decoder }); |
||
447 | assert.deepEqual(obj, { a: 'こんにちは!' }); |
||
448 | ``` |
||
449 | |||
450 | ### RFC 3986 and RFC 1738 space encoding |
||
451 | |||
452 | RFC3986 used as default option and encodes ' ' to *%20* which is backward compatible. |
||
453 | In the same time, output can be stringified as per RFC1738 with ' ' equal to '+'. |
||
454 | |||
455 | ``` |
||
456 | assert.equal(qs.stringify({ a: 'b c' }), 'a=b%20c'); |
||
457 | assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC3986' }), 'a=b%20c'); |
||
458 | assert.equal(qs.stringify({ a: 'b c' }, { format : 'RFC1738' }), 'a=b+c'); |
||
459 | ``` |
||
460 | |||
461 | [1]: https://npmjs.org/package/qs |
||
462 | [2]: http://versionbadg.es/ljharb/qs.svg |
||
463 | [3]: https://api.travis-ci.org/ljharb/qs.svg |
||
464 | [4]: https://travis-ci.org/ljharb/qs |
||
465 | [5]: https://david-dm.org/ljharb/qs.svg |
||
466 | [6]: https://david-dm.org/ljharb/qs |
||
467 | [7]: https://david-dm.org/ljharb/qs/dev-status.svg |
||
468 | [8]: https://david-dm.org/ljharb/qs?type=dev |
||
469 | [9]: https://ci.testling.com/ljharb/qs.png |
||
470 | [10]: https://ci.testling.com/ljharb/qs |
||
471 | [11]: https://nodei.co/npm/qs.png?downloads=true&stars=true |
||
472 | [license-image]: http://img.shields.io/npm/l/qs.svg |
||
473 | [license-url]: LICENSE |
||
474 | [downloads-image]: http://img.shields.io/npm/dm/qs.svg |
||
475 | [downloads-url]: http://npm-stat.com/charts.html?package=qs |