Jiahonzheng's Blog

对比 encodeURI 和 encodeURIComponent

字数统计: 532阅读时长: 2 min
2019/11/20 Share

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

转义范围

encodeURI

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

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

encodeURIComponent

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

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

二者对比

encodeURIComponentencodeURI 可转义更多的字符:

; , / ? : @ & = + $ #

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

1
2
3
4
5
6
7
8
9
10
11
12
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 进行编码,则会出现参数丢失的问题。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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 进行编码,则会出现链接无法访问的问题。

1
2
3
4
5
6
7
8
9
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));

参考资料

CATALOG
  1. 1. 转义范围
    1. 1.1. encodeURI
    2. 1.2. encodeURIComponent
    3. 1.3. 二者对比
  2. 2. 使用场景
    1. 2.1. 转义内容作为 URI 参数
    2. 2.2. 转义内容作为独立 URI
  3. 3. 参考资料