qs.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Copyright Joyent, Inc. and other Node contributors.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a
  4. // copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to permit
  8. // persons to whom the Software is furnished to do so, subject to the
  9. // following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included
  12. // in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  17. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
  18. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  21. // If obj.hasOwnProperty has been overridden, then calling
  22. // obj.hasOwnProperty(prop) will break.
  23. // See: https://github.com/joyent/node/issues/1707
  24. function hasOwnProperty(obj, prop) {
  25. return Object.prototype.hasOwnProperty.call(obj, prop);
  26. }
  27. var isArray = Array.isArray || function (xs) {
  28. return Object.prototype.toString.call(xs) === '[object Array]';
  29. };
  30. function stringifyPrimitive(v) {
  31. switch (typeof v) {
  32. case 'string':
  33. return v;
  34. case 'boolean':
  35. return v ? 'true' : 'false';
  36. case 'number':
  37. return isFinite(v) ? v : '';
  38. default:
  39. return '';
  40. }
  41. }
  42. export function stringify (obj, sep, eq, name) {
  43. sep = sep || '&';
  44. eq = eq || '=';
  45. if (obj === null) {
  46. obj = undefined;
  47. }
  48. if (typeof obj === 'object') {
  49. return map(objectKeys(obj), function(k) {
  50. var ks = encodeURIComponent(stringifyPrimitive(k)) + eq;
  51. if (isArray(obj[k])) {
  52. return map(obj[k], function(v) {
  53. return ks + encodeURIComponent(stringifyPrimitive(v));
  54. }).join(sep);
  55. } else {
  56. return ks + encodeURIComponent(stringifyPrimitive(obj[k]));
  57. }
  58. }).join(sep);
  59. }
  60. if (!name) return '';
  61. return encodeURIComponent(stringifyPrimitive(name)) + eq +
  62. encodeURIComponent(stringifyPrimitive(obj));
  63. };
  64. function map (xs, f) {
  65. if (xs.map) return xs.map(f);
  66. var res = [];
  67. for (var i = 0; i < xs.length; i++) {
  68. res.push(f(xs[i], i));
  69. }
  70. return res;
  71. }
  72. var objectKeys = Object.keys || function (obj) {
  73. var res = [];
  74. for (var key in obj) {
  75. if (Object.prototype.hasOwnProperty.call(obj, key)) res.push(key);
  76. }
  77. return res;
  78. };
  79. export function parse(qs, sep, eq, options) {
  80. sep = sep || '&';
  81. eq = eq || '=';
  82. var obj = {};
  83. if (typeof qs !== 'string' || qs.length === 0) {
  84. return obj;
  85. }
  86. var regexp = /\+/g;
  87. qs = qs.split(sep);
  88. var maxKeys = 1000;
  89. if (options && typeof options.maxKeys === 'number') {
  90. maxKeys = options.maxKeys;
  91. }
  92. var len = qs.length;
  93. // maxKeys <= 0 means that we should not limit keys count
  94. if (maxKeys > 0 && len > maxKeys) {
  95. len = maxKeys;
  96. }
  97. for (var i = 0; i < len; ++i) {
  98. var x = qs[i].replace(regexp, '%20'),
  99. idx = x.indexOf(eq),
  100. kstr, vstr, k, v;
  101. if (idx >= 0) {
  102. kstr = x.substr(0, idx);
  103. vstr = x.substr(idx + 1);
  104. } else {
  105. kstr = x;
  106. vstr = '';
  107. }
  108. k = decodeURIComponent(kstr);
  109. v = decodeURIComponent(vstr);
  110. if (!hasOwnProperty(obj, k)) {
  111. obj[k] = v;
  112. } else if (isArray(obj[k])) {
  113. obj[k].push(v);
  114. } else {
  115. obj[k] = [obj[k], v];
  116. }
  117. }
  118. return obj;
  119. };
  120. export default {
  121. encode: stringify,
  122. stringify: stringify,
  123. decode: parse,
  124. parse: parse
  125. }
  126. export {stringify as encode, parse as decode};