@@ -146,6 +146,62 @@ var withDots = qs.parse('a.b=c', { allowDots: true });
146146assert .deepEqual (withDots, { a: { b: ' c' } });
147147```
148148
149+ If you have to deal with legacy browsers or services, there's
150+ also support for decoding percent-encoded octets as iso-8859-1:
151+
152+ ``` javascript
153+ var oldCharset = qs .parse (' a=%A7' , { charset: ' iso-8859-1' });
154+ assert .deepEqual (oldCharset, { a: ' §' });
155+ ```
156+
157+ Some services add an initial ` utf8=✓ ` value to forms so that old
158+ Internet Explorer versions are more likely to submit the form as
159+ utf-8. Additionally, the server can check the value against wrong
160+ encodings of the checkmark character and detect that a query string
161+ or ` application/x-www-form-urlencoded ` body was * not* sent as
162+ utf-8, eg. if the form had an ` accept-charset ` parameter or the
163+ containing page had a different character set.
164+
165+ ** qs** supports this mechanism via the ` charsetSentinel ` option.
166+ If specified, the ` utf8 ` parameter will be omitted from the
167+ returned object. It will be used to switch to ` iso-8859-1 ` /` utf-8 `
168+ mode depending on how the checkmark is encoded.
169+
170+ ** Important** : When you specify both the ` charset ` option and the
171+ ` charsetSentinel ` option, the ` charset ` will be overridden when
172+ the request contains a ` utf8 ` parameter from which the actual
173+ charset can be deduced. In that sense the ` charset ` will behave
174+ as the default charset rather than the authoritative charset.
175+
176+ ``` javascript
177+ var detectedAsUtf8 = qs .parse (' utf8=%E2%9C%93&a=%C3%B8' , {
178+ charset: ' iso-8859-1' ,
179+ charsetSentinel: true
180+ });
181+ assert .deepEqual (detectedAsUtf8, { a: ' ø' });
182+
183+ // Browsers encode the checkmark as ✓ when submitting as iso-8859-1:
184+ var detectedAsIso8859_1 = qs .parse (' utf8=%26%2310003%3B&a=%F8' , {
185+ charset: ' utf-8' ,
186+ charsetSentinel: true
187+ });
188+ assert .deepEqual (detectedAsIso8859_1, { a: ' ø' });
189+ ```
190+
191+ If you want to decode the ` &#...; ` syntax to the actual character,
192+ you can specify the ` interpretNumericEntities ` option as well:
193+
194+ ``` javascript
195+ var detectedAsIso8859_1 = qs .parse (' a=%26%239786%3B' , {
196+ charset: ' iso-8859-1' ,
197+ interpretNumericEntities: true
198+ });
199+ assert .deepEqual (detectedAsIso8859_1, { a: ' ☺' });
200+ ```
201+
202+ It also works when the charset has been detected in ` charsetSentinel `
203+ mode.
204+
149205### Parsing Arrays
150206
151207** qs** can also parse arrays using a similar ` [] ` notation:
@@ -426,10 +482,40 @@ var nullsSkipped = qs.stringify({ a: 'b', c: null}, { skipNulls: true });
426482assert .equal (nullsSkipped, ' a=b' );
427483```
428484
485+ If you're communicating with legacy systems, you can switch to ` iso-8859-1 `
486+ using the ` charset ` option:
487+
488+ ``` javascript
489+ var iso = qs .stringify ({ æ: ' æ' }, { charset: ' iso-8859-1' });
490+ assert .equal (iso, ' %E6=%E6' );
491+ ```
492+
493+ Characters that don't exist in ` iso-8859-1 ` will be converted to numeric
494+ entities, similar to what browsers do:
495+
496+ ``` javascript
497+ var numeric = qs .stringify ({ a: ' ☺' }, { charset: ' iso-8859-1' });
498+ assert .equal (numeric, ' a=%26%239786%3B' );
499+ ```
500+
501+ You can use the ` charsetSentinel ` option to announce the character by
502+ including an ` utf8=✓ ` parameter with the proper encoding if the checkmark,
503+ similar to what Ruby on Rails and others do when submitting forms.
504+
505+ ``` javascript
506+ var sentinel = qs .stringify ({ a: ' ☺' }, { charsetSentinel: true });
507+ assert .equal (sentinel, ' utf8=%E2%9C%93&a=%E2%98%BA' );
508+
509+ var isoSentinel = qs .stringify ({ a: ' æ' }, { charsetSentinel: true , charset: ' iso-8859-1' });
510+ assert .equal (isoSentinel, ' utf8=%26%2310003%3B&a=%E6' );
511+ ```
512+
429513### Dealing with special character sets
430514
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.
515+ By default the encoding and decoding of characters is done in ` utf-8 ` ,
516+ and ` iso-8859-1 ` support is also built in via the ` charset ` parameter.
517+
518+ If you wish to encode querystrings to a different character set (i.e.
433519[ Shift JIS] ( https://en.wikipedia.org/wiki/Shift_JIS ) ) you can use the
434520[ ` qs-iconv ` ] ( https://github.com/martinheidegger/qs-iconv ) library:
435521
0 commit comments