// query string
export function qs(obj = {}) {
  const encode = encodeURIComponent;
  return Object.keys(obj)
    .map(k => encode(k) + '=' + encode(obj[k]))
    .join('&');
}

// 和qs相同，对数组做特殊处理
export function formData(obj = {}) {
  const encode = encodeURIComponent;
  return Object.keys(obj)
    .map(k => {
      if (Array.isArray(obj[k])) {
        console.log(encode(k) + '=' + obj[k].join(','));
        return encode(k) + '=' + obj[k].join(',')
      }
      return encode(k) + '=' + encode(obj[k]);
    })
    .join('&');

  // if (Object.keys(obj).length) {
  //   return Object.keys(obj)
  //     .reduce((formData, k) => {
  //       formData.append(k, obj[k]);
  //       return formData;
  //     }, new FormData());
  // }
  return null;
}

@@ -1,20 +1,33 @@
-// 
+ /**%0A  * %E7%AE%80%E5%8C%96%E7%89%88
 query
- 
 string%0A
+  */%0A
 expo
@@ -188,24 +188,58 @@
 %7D%0A%0A/
-/ %E5%92%8Cqs%E7%9B%B8%E5%90%8C%EF%BC%8C%E5%AF%B9%E6%95%B0%E7%BB%84%E5%81%9A%E7%89%B9%E6%AE%8A%E5%A4%84%E7%90%86
+**%0A * %E5%92%8Cqs%E7%B1%BB%E4%BC%BC%EF%BC%8C%E7%94%A8%E4%BA%8E%E5%8F%91%E9%80%81application/x-www-urlencoded%E8%A1%A8%E5%8D%95%0A */
 %0Aexp
@@ -251,24 +251,25 @@
 unction 
-formData
+urlencode
 (obj = %7B
@@ -279,293 +279,923 @@
 %7B%0A  
-const encode = encodeURIComponent;%0A  return Object.keys(obj)%0A    .map(k =%3E %7B%0A      if (Array.isArray(obj%5Bk%5D)) %7B%0A        console.log(encode(k) + '=' + obj%5Bk%5D.join(','));%0A        return encode(k) + '=' + obj%5Bk%5D.join(',')%0A      %7D%0A      return encode(k)
+return stringify(obj);%0A%7D%0A%0A// %E6%8B%B7%E8%B4%9D%E8%87%AAneedle%EF%BC%8C%E4%B8%BA%E4%BA%86%E4%BF%9D%E8%AF%81encode%E7%BB%93%E6%9E%9C%E5%92%8Cleanote-desktop%E5%AE%8C%E5%85%A8%E4%B8%80%E8%87%B4%0Afunction stringify(obj, prefix) %7B%0A  if (prefix && (obj === null %7C%7C typeof obj == 'undefined')) %7B%0A    return prefix + '=';%0A  %7D else if (obj.constructor == Array) %7B%0A    return stringifyArray(obj, prefix);%0A  %7D else if (obj !== null && typeof obj == 'object') %7B%0A    return stringifyObject(obj, prefix);%0A  %7D else if (prefix) %7B // string inside array or hash%0A    return prefix + '=' + encodeURIComponent(String(obj));%0A  %7D else if (String(obj).indexOf('=') !== -1) %7B // string with equal sign%0A    return String(obj);%0A  %7D else %7B%0A    throw new TypeError('Cannot build a querystring out of: ' + obj);%0A  %7D%0A%7D;%0A%0Afunction stringifyArray(arr, prefix) %7B%0A  var ret = %5B%5D;%0A%0A  for (var i = 0, len = arr.length; i %3C len; i++) %7B%0A    if (prefix)%0A      ret.push(stringify(arr%5Bi%5D, prefix
  + '
-=
+%5B
 ' + 
-encode(obj%5Bk%5D
+i + '%5D'));%0A    else%0A      ret.push(stringify(arr%5Bi%5D)
 );%0A
-  
   %7D
-)%0A    
+%0A%0A  return ret
 .joi
@@ -1206,214 +1206,244 @@
 ');%0A
-%0A  // if (Object.keys(obj).length) %7B%0A  //   return Object.keys(obj)%0A  //     .reduce((formData, k) =%3E %7B%0A  //       formData.append(k, obj%5Bk%5D);
+%7D%0A%0Afunction stringifyObject(obj, prefix) %7B%0A  var ret = %5B%5D;%0A%0A  Object.keys(obj).forEach(function(key) %7B%0A    ret.push(stringify(obj%5Bkey%5D, prefix
 %0A  
-//
     
-   return formData;%0A  //     %7D, new FormData(
+? prefix + '%5B' + encodeURIComponent(key) + '%5D'%0A      : encodeURIComponent(key
 ))
+)
 ;%0A  
-// %7D
+%7D)%0A
 %0A  r
@@ -1448,16 +1448,25 @@
  return 
-null
+ret.join('&')
 ;%0A%7D%0A

stringify obj in the same way as needle