`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) )