首先你要用这两个函数的时候,大概率是准备把一些参数拼成url。
把参数拼成url之后,大概率要在另外的页面,把url字符串解析为参数,然后做一系列的操作。
我们先从解析说起,大概率你是面对着这样的形式:?foo=123&bar=456&name=789。
要把这个字符串转换成可用的参数,其实很简单,首先去掉头部的?,然后字符串根据&做split,得到类似foo=123、bar=456的键值对,然后对这些键值对再根据=做split,就能一一分离出key和value,小菜一碟,随便手撸。
但你想过没有,如果&和=出现在不该出现的地方,是不是解析就全乱套了?
有点慌,于是我们去看看encodeURI和encodeURIComponent对于&和=的转义
encodeURI('&'); // &
encodeURI('='); // =
encodeURIComponent('&'); // %26
encodeURIComponent('='); // %3D
看到这个小实验结果,你隐隐约约有个猜想:如果值里面有&、=字符,而没有用encodeURIComponent去转化的话,后面解析的时候很有可能得到错误的结果,因为出现了分隔符以外的&、=。
我们看这个完整的例子:
// 打算通过URL传递一个json字符串
var jsonStr = JSON.stringify({
age: '18',
name: '&Job',
sex: '=alive',
});
// 传给页面是params=json字符串
var testStr1 = '?params=' + encodeURI(jsonStr);
var testStr2 = '?params=' + encodeURIComponent(jsonStr);
// 把url字符串转为obj的函数,通过&和=去分隔
function searchToObj(search, decodeMethod) {
var result = {};
if (!search) return result;
if (!decodeMethod) {
decodeMethod = function(val) {
return val;
}
}
search = search.slice(1); // 把开头的?过滤掉
var searchArr = search.split('&');
searchArr.forEach(function(kvPair) {
var kvArr = kvPair.split('=');
result[kvArr[0]] = decodeMethod(kvArr[1])
});
return result;
}
// 解析还原传过来的参数
var decodeStr1 = searchToObj(testStr1);
var decodeStr2 = searchToObj(testStr2);
发现用encodeURIComponent解析还原的参数是:params: "%7B%22age%22%3A%2218%22%2C%22name%22%3A%22%26Job%22%2C%22sex%22%3A%22%3Dalive%22%7D",是对的
而用encodeURI解析还原的参数是:Job%22,%22sex%22:%22: "alive%22%7D"和params: "%7B%22age%22:%2218%22,%22name%22:%22",莫名其妙多了个Job%22,%22sex%22:%22的键值对
结论:拼接url时请使用encodeURIComponent,以防止拼接内容中含有&、=及其他未转义的字符,而导致难以预期的bug。