diff --git a/README.md b/README.md index 3a13705f..7fbe063a 100644 --- a/README.md +++ b/README.md @@ -162,13 +162,13 @@ or `application/x-www-form-urlencoded` body was *not* sent as utf-8, eg. if the form had an `accept-charset` parameter or the containing page had a different character set. -**qs** supports this mechanism via the `utf8Sentinel` option. +**qs** supports this mechanism via the `charsetSentinel` option. If specified, the `utf8` parameter will be omitted from the returned object. It will be used to switch to `iso-8859-1`/`utf-8` mode depending on how the checkmark is encoded. **Important**: When you specify both the `charset` option and the -`utf8Sentinel` option, the `charset` will be overridden when +`charsetSentinel` option, the `charset` will be overridden when the request contains a `utf8` parameter from which the actual charset can be deduced. In that sense the `charset` will behave as the default charset rather than the authoritative charset. @@ -176,14 +176,14 @@ as the default charset rather than the authoritative charset. ```javascript var detectedAsUtf8 = qs.parse('utf8=%E2%9C%93&a=%C3%B8', { charset: 'iso-8859-1', - utf8Sentinel: true + charsetSentinel: true }); assert.deepEqual(detectedAsUtf8, { a: 'ø' }); // Browsers encode the checkmark as ✓ when submitting as iso-8859-1: var detectedAsIso8859_1 = qs.parse('utf8=%26%2310003%3B&a=%F8', { charset: 'utf-8', - utf8Sentinel: true + charsetSentinel: true }); assert.deepEqual(detectedAsIso8859_1, { a: 'ø' }); ``` @@ -199,7 +199,7 @@ var detectedAsIso8859_1 = qs.parse('a=%26%239786%3B', { assert.deepEqual(detectedAsIso8859_1, { a: '☺' }); ``` -It also works when the charset has been detected in `utf8Sentinel` +It also works when the charset has been detected in `charsetSentinel` mode. ### Parsing Arrays @@ -498,15 +498,15 @@ var numeric = qs.stringify({ a: '☺' }, { charset: 'iso-8859-1' }); assert.equal(numeric, 'a=%26%239786%3B'); ``` -You can use the `utf8Sentinel` option to announce the character by +You can use the `charsetSentinel` option to announce the character by including an `utf8=✓` parameter with the proper encoding if the checkmark, similar to what Ruby on Rails and others do when submitting forms. ```javascript -var sentinel = qs.stringify({ a: '☺' }, { utf8Sentinel: true }); +var sentinel = qs.stringify({ a: '☺' }, { charsetSentinel: true }); assert.equal(sentinel, 'utf8=%E2%9C%93&a=%E2%98%BA'); -var isoSentinel = qs.stringify({ a: 'æ' }, { utf8Sentinel: true, charset: 'iso-8859-1' }); +var isoSentinel = qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }); assert.equal(isoSentinel, 'utf8=%26%2310003%3B&a=%E6'); ``` diff --git a/lib/parse.js b/lib/parse.js index 89cbce91..25eea389 100644 --- a/lib/parse.js +++ b/lib/parse.js @@ -16,7 +16,7 @@ var defaults = { parameterLimit: 1000, plainObjects: false, strictNullHandling: false, - utf8Sentinel: false + charsetSentinel: false }; var interpretNumericEntities = function (str) { @@ -34,7 +34,7 @@ var isoSentinel = 'utf8=%26%2310003%3B'; // encodeURIComponent('✓') // These are the percent-encoded utf-8 octets representing a checkmark, indicating // that the request actually is utf-8 encoded. -var utf8Sentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') +var charsetSentinel = 'utf8=%E2%9C%93'; // encodeURIComponent('✓') var parseValues = function parseQueryStringValues(str, options) { var obj = {}; @@ -48,10 +48,10 @@ var parseValues = function parseQueryStringValues(str, options) { if (charset !== undefined && charset !== 'utf-8' && charset !== 'iso-8859-1') { throw new Error('The charset option must be either utf-8, iso-8859-1, or undefined'); } - if (options.utf8Sentinel) { + if (options.charsetSentinel) { for (i = 0; i < parts.length; ++i) { if (parts[i].indexOf('utf8=') === 0) { - if (parts[i] === utf8Sentinel) { + if (parts[i] === charsetSentinel) { charset = 'utf-8'; } else if (parts[i] === isoSentinel) { charset = 'iso-8859-1'; diff --git a/lib/stringify.js b/lib/stringify.js index 61c3dfa7..5bf5e8b5 100644 --- a/lib/stringify.js +++ b/lib/stringify.js @@ -215,7 +215,7 @@ module.exports = function (object, opts) { var joined = keys.join(delimiter); var prefix = options.addQueryPrefix === true ? '?' : ''; - if (options.utf8Sentinel) { + if (options.charsetSentinel) { if (charset === 'iso-8859-1') { // encodeURIComponent('✓'), the "numeric entity" representation of a checkmark prefix += 'utf8=%26%2310003%3B&'; diff --git a/test/parse.js b/test/parse.js index 53a8ce1a..f0ce23b5 100644 --- a/test/parse.js +++ b/test/parse.js @@ -595,32 +595,32 @@ test('parse()', function (t) { var urlEncodedNumSmiley = '%26%239786%3B'; t.test('prefers an utf-8 charset specified by the utf8 sentinel to a default charset of iso-8859-1', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true, charset: 'iso-8859-1' }), { ø: 'ø' }); + st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'iso-8859-1' }), { ø: 'ø' }); st.end(); }); t.test('prefers an iso-8859-1 charset specified by the utf8 sentinel to a default charset of utf-8', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true, charset: 'utf-8' }), { 'ø': 'ø' }); + st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { 'ø': 'ø' }); st.end(); }); t.test('does not require the utf8 sentinel to be defined before the parameters whose decoding it affects', function (st) { - st.deepEqual(qs.parse('a=' + urlEncodedOSlashInUtf8 + '&utf8=' + urlEncodedNumCheckmark, { utf8Sentinel: true, charset: 'utf-8' }), { a: 'ø' }); + st.deepEqual(qs.parse('a=' + urlEncodedOSlashInUtf8 + '&utf8=' + urlEncodedNumCheckmark, { charsetSentinel: true, charset: 'utf-8' }), { a: 'ø' }); st.end(); }); t.test('should ignore an utf8 sentinel with an unknown value', function (st) { - st.deepEqual(qs.parse('utf8=foo&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true, charset: 'utf-8' }), { ø: 'ø' }); + st.deepEqual(qs.parse('utf8=foo&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true, charset: 'utf-8' }), { ø: 'ø' }); st.end(); }); t.test('uses the utf8 sentinel to switch to utf-8 when no default charset is given', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true }), { ø: 'ø' }); + st.deepEqual(qs.parse('utf8=' + urlEncodedCheckmarkInUtf8 + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { ø: 'ø' }); st.end(); }); t.test('uses the utf8 sentinel to switch to iso-8859-1 when no default charset is given', function (st) { - st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { utf8Sentinel: true }), { 'ø': 'ø' }); + st.deepEqual(qs.parse('utf8=' + urlEncodedNumCheckmark + '&' + urlEncodedOSlashInUtf8 + '=' + urlEncodedOSlashInUtf8, { charsetSentinel: true }), { 'ø': 'ø' }); st.end(); }); diff --git a/test/stringify.js b/test/stringify.js index 38075ed3..c54c0df3 100644 --- a/test/stringify.js +++ b/test/stringify.js @@ -609,12 +609,12 @@ test('stringify()', function (t) { }); t.test('adds the right sentinel when instructed to and the charset is utf-8', function (st) { - st.equal(qs.stringify({ a: 'æ' }, { utf8Sentinel: true, charset: 'utf-8' }), 'utf8=%E2%9C%93&a=%C3%A6'); + st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'utf-8' }), 'utf8=%E2%9C%93&a=%C3%A6'); st.end(); }); t.test('adds the right sentinel when instructed to and the charset is iso-8859-1', function (st) { - st.equal(qs.stringify({ a: 'æ' }, { utf8Sentinel: true, charset: 'iso-8859-1' }), 'utf8=%26%2310003%3B&a=%E6'); + st.equal(qs.stringify({ a: 'æ' }, { charsetSentinel: true, charset: 'iso-8859-1' }), 'utf8=%26%2310003%3B&a=%E6'); st.end(); });