You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
118 lines
2.5 KiB
118 lines
2.5 KiB
'use strict'; |
|
|
|
var has = Object.prototype.hasOwnProperty |
|
, undef; |
|
|
|
/** |
|
* Decode a URI encoded string. |
|
* |
|
* @param {String} input The URI encoded string. |
|
* @returns {String|Null} The decoded string. |
|
* @api private |
|
*/ |
|
function decode(input) { |
|
try { |
|
return decodeURIComponent(input.replace(/\+/g, ' ')); |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* Attempts to encode a given input. |
|
* |
|
* @param {String} input The string that needs to be encoded. |
|
* @returns {String|Null} The encoded string. |
|
* @api private |
|
*/ |
|
function encode(input) { |
|
try { |
|
return encodeURIComponent(input); |
|
} catch (e) { |
|
return null; |
|
} |
|
} |
|
|
|
/** |
|
* Simple query string parser. |
|
* |
|
* @param {String} query The query string that needs to be parsed. |
|
* @returns {Object} |
|
* @api public |
|
*/ |
|
function querystring(query) { |
|
var parser = /([^=?#&]+)=?([^&]*)/g |
|
, result = {} |
|
, part; |
|
|
|
while (part = parser.exec(query)) { |
|
var key = decode(part[1]) |
|
, value = decode(part[2]); |
|
|
|
// |
|
// Prevent overriding of existing properties. This ensures that build-in |
|
// methods like `toString` or __proto__ are not overriden by malicious |
|
// querystrings. |
|
// |
|
// In the case if failed decoding, we want to omit the key/value pairs |
|
// from the result. |
|
// |
|
if (key === null || value === null || key in result) continue; |
|
result[key] = value; |
|
} |
|
|
|
return result; |
|
} |
|
|
|
/** |
|
* Transform a query string to an object. |
|
* |
|
* @param {Object} obj Object that should be transformed. |
|
* @param {String} prefix Optional prefix. |
|
* @returns {String} |
|
* @api public |
|
*/ |
|
function querystringify(obj, prefix) { |
|
prefix = prefix || ''; |
|
|
|
var pairs = [] |
|
, value |
|
, key; |
|
|
|
// |
|
// Optionally prefix with a '?' if needed |
|
// |
|
if ('string' !== typeof prefix) prefix = '?'; |
|
|
|
for (key in obj) { |
|
if (has.call(obj, key)) { |
|
value = obj[key]; |
|
|
|
// |
|
// Edge cases where we actually want to encode the value to an empty |
|
// string instead of the stringified value. |
|
// |
|
if (!value && (value === null || value === undef || isNaN(value))) { |
|
value = ''; |
|
} |
|
|
|
key = encode(key); |
|
value = encode(value); |
|
|
|
// |
|
// If we failed to encode the strings, we should bail out as we don't |
|
// want to add invalid strings to the query. |
|
// |
|
if (key === null || value === null) continue; |
|
pairs.push(key +'='+ value); |
|
} |
|
} |
|
|
|
return pairs.length ? prefix + pairs.join('&') : ''; |
|
} |
|
|
|
// |
|
// Expose the module. |
|
// |
|
exports.stringify = querystringify; |
|
exports.parse = querystring;
|
|
|