路径传参一定要转码,不然在解析的时候要报错,特别用一些不可控的数据作为参数!
案例
例如:www.xxx.com?id=1&name=小明&小花
看我以前是这么解析的。这绝对报错。
/** 路径参数解析 */
export const parsePathParams = (url: string, defaultValue: any = undefined) => {
if (isStr(url)) {
try {
const splitIndex = url.indexOf('?');
let content: any = {};
(splitIndex === -1 ? url : url.slice(splitIndex))
.replace(/"/g, '\\"')
.split('&')
.forEach((e) => {
const [key, val] = e.split('=');
content[key] = decodeURIComponent(val);
});
return content;
} catch (error) {}
}
return defaultValue;
};
解决办法
后面我找到了这个:以UTF-8编码编码所有字符串
encodeURIComponent(string); 编码
decodeURIComponent(string); 解码
得到了下面两个方法
/** 路径参数解析 */
export const parsePathParams = (url: string, defaultValue: any = undefined) => {
if (isStr(url)) {
try {
const splitIndex = url.indexOf('?');
let content: any = defaultValue;
(splitIndex === -1 ? url : url.slice(splitIndex + 1))
.replace(/"/g, '\\"')
.split('&')
.forEach((e) => {
if (e) {
const [key, val] = e.split('=');
if (content === defaultValue) content = {};
content[key] = decodeURIComponent(val);
}
});
return content;
} catch (error) {}
}
return defaultValue;
};
/**
* 对象转路径参数
*/
export const toPathParams = (obj: { [key: string]: any }, join = '&') => {
if (!isFullObj(obj)) return '';
let _result: any = [];
let keys = Object.keys(obj);
for (let index = 0; index < keys.length; index++) {
const key = keys[index];
const value = obj[key];
if (isArr(value)) {
value.forEach((_value) => {
_result.push(key + '=' + encodeURIComponent(_value));
});
} else {
_result.push(key + '=' + encodeURIComponent(value));
}
}
return _result.join(join);
};
兼容处理
注:如果你已经用特殊符号做为了参数且为转码,那么你在做解释的时候过滤一些呗
replace() 方法如果直接用str.replace("-","!") 只会替换第一个匹配的字符.
而str.replace(/\-/g,"!")则可以替换掉全部匹配的字符(g为全局标志)。
// js中替换字符变量如下:
data2=data2.replace(/\%/g,"%25");
data2=data2.replace(/\#/g,"%23");
data2=data2.replace(/\&/g,"%26");
最后附上URL特殊符号及编码