`qs.parse` 的简单实现

qs.parse

qs.parse 的简单版本实现。支持hash,支持多链接 http://example.cn/BindingMobileNumber.html?redirect_url=http%3A%2F%2Fexample.cn%2Factivity%2Fshake.html%3FmktId%3D201805070000008%26subType%3D103

Source code:

/**
 * getQueryString
 * @author VuChan
 * @desc  生成链接后面选项参数
 * @param   {String}  url
 * @param   {Object}  Options
 * @return  {Object | null}
 * @design 穷举法:
 *  0. a.com? | a.com?& | a.com?&=&1=2&&
 *  1. a.com?a=1&b=2&c=&d=3
 *  2. a.com?a=1&b=2&c=&d=3/#/hash
 *  3. a.com/#/hash?a=1&b=2&c=&d=3
 *  4. http://mcar.feewee.cn/uploading.html/#/?shopId=5&orderId=231&loanOrderId=59&orderAmount=64900.00&period=36&downPayRate=0.1
 *  5. http://mcar.feewee.cn/uploading.html?shopId=5&orderId=231&loanOrderId=59&orderAmount=64900.00&period=36&downPayRate=0.1/#/
 *  6. http://devwc.feewee.cn/BindingMobileNumber.html?redirect_url=http%3A%2F%2Fdevwc.feewee.cn%2Factivity%2Fshake.html%3FmktId%3D201805070000008%26subType%3D103
 * @requires
 *  1. 减去 hash 符号提取正常的 url
 *  2. 仅提取正确queryString
 *  3. 如果是 number 则需要转化成 number
 * @example
 *  getQueryString(location.href)
 */
export const getQueryString = (
  url = window.location.href,
  options = {
    cutHash: true, // replace hash `/#/{path}` to be ''
    decoder: decodeURIComponent, // self decoder or browser's
    decodeEach: false,
    all: true, // need all value whatever it is valid or not
    encode: false, // if u need? `false | encodeURLComponent | function`
    placeholder: '', // if value is invalid, so puts the `placeholder`
  },
) => {
  const defaultOptions = {
    cutHash: true, // replace hash `/#/{path}` to be ''
    decoder: decodeURIComponent, // self decoder or browser's
    decodeEach: false,
    all: true, // need all value whatever it is valid or not
    encode: false, // if u need? `false | encodeURLComponent | function`
    placeholder: '', // if value is invalid, so puts the `placeholder`
  };

  options = { ...defaultOptions, ...options };

  const parse = str => {
    if (!str || !str.trim().length) return null;
    else {
      if (
        !~str.indexOf('?') &&
        (~str.indexOf('=') &&
        ~str.indexOf('&'))
      ) {
        str = str.split('&').map(t => t.trim()).filter(t => ~t.indexOf('=')).map(t => (options.decodeEach ? options.decoder(t) : t));
      } else {
        str = [str];
      }

      if (str.length) {
        return str.reduce((r, c) => {
          c = c.split('=');
          if (c.length > 2) c = [c.shift(), c.join('=')];

          if (c[0]) {
            if (c[1]) {
              r[c[0]] = +c[1] ? +c[1] : c[1];
            } else {
              r[c[0]] = options.placeholder;
            }
          }

          return r;
        }, {});
      } else {
        return null;
      }
    }
  };

  let str = !options.decodeEach && typeof options.decoder === 'function' ? options.decoder(url) : url;

  // type check of str value
  if (!str || typeof str !== 'string' || !str.trim()) return null;
  if (options.cutHash) {
    // match this format like -> /#/ | /#/{word}
    str = str.replace(/\/?\#\/(\w*\b)?/, '');
  }

  if (~str.indexOf('?')) {
    // splits `?` only once
    str = str.split('?');
    if (str.length > 2) {
      str = [str.shift(), str.join('?')];
    }

    str = str[1];
  } else {
    // if no any `?` sign returns null
    return null
  }

  return parse(str);
};

test

s0 = 'a.com?'
s1 =  'a.com?&' 
s2 =  'a.com?&=&1=2&&'
s3 = 'a.com?a=1&b=2&c=&d=3'
s4 = 'a.com?a=1&b=2&c=&d=3/#/hash'
s5 = 'a.com/#/hash?a=1&b=2&c=&d=3'
s6 = 'http://example.cn/uploading.html/#/?shopId=5&orderId=231&loanOrderId=59&orderAmount=64900.00&period=36&downPayRate=0.1'
s7 = 'http://example.cn/uploading.html?shopId=5&orderId=231&loanOrderId=59&orderAmount=64900.00&period=36&downPayRate=0.1/#/'
s8 = 'http://example.cn/BindingMobileNumber.html?redirect_url=http%3A%2F%2Fexample.cn%2Factivity%2Fshake.html%3FmktId%3D201805070000008%26subType%3D103'

console.log( getQueryString(s0) )
console.log( getQueryString(s1) )
console.log( getQueryString(s2) )
console.log( getQueryString(s3) )
console.log( getQueryString(s4) )
console.log( getQueryString(s5) )
console.log( getQueryString(s6) )
console.log( getQueryString(s7) )
console.log( getQueryString(s8) )

results

results

posted @ 2018-07-20 17:11  月光宝盒造梦师  阅读(471)  评论(0编辑  收藏  举报