encodeURIencodeURIComponent 都可用于对 URL 进行 转义编码,但二者之间是存在差异的,其应用场景是不相同的。

转义范围

encodeURI

encodeURI 可转义所有字符,除了以下字符:

A-Z a-z 0-9 ; , / ? : @ & = + $ - \_ . ! ~ \* ' ( ) #

encodeURIComponent

encodeURIComponent 可转义所有字符,除了以下字符:

A-Z a-z 0-9 - _ . ! ~ * ' ( )

二者对比

encodeURIComponentencodeURI 可转义更多的字符:

; , / ? : @ & = + $ #

我们可以执行以下代码,查看二者转义范围的差异。

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&param2=value2';

// 若使用 encodeURI 对 url 进行编码,发现 param2=value2 被识别为 b.com 的参数, a.com 丢失 param2 参数。
// https://b.com?param1=https://a.com/?param1=value1&param2=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&param2=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));

参考资料