encodeURI
和 encodeURIComponent
都可用于对 URL 进行 转义编码,但二者之间是存在差异的,其应用场景是不相同的。
转义范围
encodeURI
encodeURI
可转义所有字符,除了以下字符:
A-Z a-z 0-9 ; , / ? : @ & = + $ - \_ . ! ~ \* ' ( ) #
encodeURIComponent
encodeURIComponent
可转义所有字符,除了以下字符:
A-Z a-z 0-9 - _ . ! ~ * ' ( )
二者对比
encodeURIComponent
比 encodeURI
可转义更多的字符:
; , / ? : @ & = + $ #
我们可以执行以下代码,查看二者转义范围的差异。
const set1 = ';,/?:@&=+$#'; // Reserved Characters
const set2 = "-_.!~*'()"; // Unescaped Characters
const set3 = 'ABC abc 123'; // Alphanumeric Characters + Space
console.log(encodeURI(set1)); // ;,/?:@&=+$#
console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24%23
console.log(encodeURI(set2)); // -_.!~*'()
console.log(encodeURIComponent(set2)); // -_.!~*'()
console.log(encodeURI(set3)); // ABC%20abc%20123
console.log(encodeURIComponent(set3)); // ABC%20abc%20123
使用场景
转义内容作为 URI 参数
若我们需要将转义内容作为 URI 参数,我们需要使用 encodeURIComponent
进行编码。若使用 encodeURI
进行编码,则会出现 参数丢失 的问题。
const urllib = require('url');
// 将 url 作为 b.com 中 param1 的参数。
function parseQueryParams(encoded) {
console.log('https://b.com?param1=' + encoded);
const { query } = urllib.parse('https://b.com?param1=' + encoded, true);
console.log({ ...query });
}
// 注意到 param1 和 param2 是属于 url 的。
const url = 'https://a.com/?param1=value1¶m2=value2';
// 若使用 encodeURI 对 url 进行编码,发现 param2=value2 被识别为 b.com 的参数, a.com 丢失 param2 参数。
// https://b.com?param1=https://a.com/?param1=value1¶m2=value2
// { param1: 'https://a.com/?param1=value1', param2: 'value2' }
parseQueryParams(encodeURI(url));
// 若使用 encodeURIComponent 对 url 进行编码,则无上述错误。
// https://b.com?param1=https%3A%2F%2Fa.com%2F%3Fparam1%3Dvalue1%26param2%3Dvalue2
// { param1: 'https://a.com/?param1=value1¶m2=value2' }
parseQueryParams(encodeURIComponent(url));
转义内容作为独立 URI
当转义内容作为独立 URI 时,我们需要使用 encodeURI
进行编码。若使用 encodeURIComponent
进行编码,则会出现 链接无法访问 的问题。
const url = 'https://api.jiahonzheng.cn/v1/echo?msg=Hello World';
// 当转义内容作为独立 URI 时,应该使用 encodeURI 。
// https://api.jiahonzheng.cn/v1/echo?msg=Hello%20World
console.log(encodeURI(url));
// 若使用 encodeURIComponent ,则会出现 URL 无法正常访问的问题。
// https%3A%2F%2Fapi.jiahonzheng.cn%2Fv1%2Fecho%3Fmsg%3DHello%20World
console.log(encodeURIComponent(url));