escape,encodeURI和encodeURIComponent的区别

2021/5/12 JavaScript

TIPS

  • escape(), unescape()
  • encodeURI(), decodeURI()
  • encodeURIComponent(), decodeURIComponent()

都是对字符串进行编码以及对应的解码,只是规则不同

以上几个都是全局函数,除此之外还有八个

函数 描述
escape() 对字符串进行编码。
unescape() 对由 escape() 编码的字符串进行解码。
encodeURI() 把字符串编码为 URI。
decodeURI() 解码某个编码的 URI。
encodeURIComponent() 把字符串编码为 URI 组件。
decodeURIComponent() 解码一个编码的 URI 组件。
Number() 把对象的值转换为数字。
String() 把对象的值转换为字符串。
parseInt() 解析一个字符串并返回一个整数。
parseFloat() 解析一个字符串并返回一个浮点数。
isNaN() 检查某个值是否是数字。
isFinite() 检查某个值是否为有穷大的数。
eval() 计算 JavaScript 字符串,并把它作为脚本代码来执行。
getClass() 返回一个 JavaObject 的 JavaClass。

另:全局属性

方法 描述
NaN 指示某个值是不是数字值。
undefined 指示未定义的值。
Infinity 代表正的无穷大的数值。
java 代表 java.* 包层级的一个 JavaPackage。
Packages 根 JavaPackage 对象。

WARNING

除了上述这14个全局函数之外,其他任何函数都不是全局函数,例如 setTimeout,它只是 window 对象提供的一个方法

# escape()与unescape() 已废弃

# escape()

escape() 函数可对字符串进行编码,这样就可以在所有的计算机上读取该字符串。

const string = '123!@#';
escape(string); // 123%21@%23
1
2

返回值:已编码的 string 的副本。其中某些字符被替换成了十六进制的转义序列。

该方法不会对 ASCII 字母和数字进行编码,也不会对下面这些 ASCII 标点符号进行编码: * @ - _ + . / 。其他所有的字符都会被转义序列替换。

# unescape()

操作方式与转义规则和 escape() 一样

// escape() 编码后的参数
const string = '123%21@%23';
unescape(string); // 123!@#
1
2
3

# encodeURI()与decodeURI()

# encodeURI()

encodeURI() 函数可把字符串作为 URI 进行编码。

const URIstring = 'http://127.0.0.1:8080/blog/?name=六先生';
encodeURI(URIstring);
// http://127.0.0.1:8080/blog/?name=%E5%85%AD%E5%85%88%E7%94%9F
1
2
3

返回值:URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。

该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( )

该方法的目的是对 URI 进行完整的编码,因此对以下在 URI 中具有特殊含义的 ASCII 标点符号,encodeURI() 函数是不会进行转义的:; / ? : @ & = + $ , #

WARNING

如果 URI 组件中含有分隔符,比如 ?#,则应当使用 encodeURIComponent() 方法分别对各组件进行编码。

encodeURI() 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 &, +, 和 = 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而 encodeURIComponent() 这个方法会对这些字符编码。

并且需要注意,如果URL需要遵循较新的 RFC3986 (opens new window) 标准,那么方括号是被保留的(给IPv6),因此对于那些没有被编码的URL部分(例如主机),可以使用下面的代码:

function fixedEncodeURI (str) {
  return encodeURI(str).replace(/%5B/g, '[').replace(/%5D/g, ']');
}
1
2
3

# decodeURI()

操作方式与转义规则和 encodeURI() 一样

encodedURI() 包含无效字符序列时,引发 URIError(“格式错误的URI序列”) 异常。

// encodedURI() 编码后的参数
const URIstring = 'http://127.0.0.1:8080/blog/?name=%E5%85%AD%E5%85%88%E7%94%9F';
decodeURI(URIstring);
// http://127.0.0.1:8080/blog/?name=六先生
1
2
3
4

# encodeURIComponent()与decodeURIComponent()

# encodeURIComponent()

encodeURIComponent() 函数可把字符串作为 URI 组件进行编码。通过将一个,两个,三个或四个表示字符的UTF-8编码的转义序列替换某些字符的每个实例来编码 URI (对于由两个“代理”字符组成的字符而言,将仅是四个转义序列) 。

const URIstring = 'http://127.0.0.1:8080/blog/?name=六先生';
encodeURIComponent(URIstring);
// http%3A%2F%2F127.0.0.1%3A8080%2Fblog%2F%3Fname%3D%E5%85%AD%E5%85%88%E7%94%9F
1
2
3

返回值:URIstring 的副本,其中的某些字符将被十六进制的转义序列进行替换。

该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ' ( )

其他字符(比如:; / ? : @ & = + $ , # 这些用于分隔 URI 组件的标点符号),都是由一个或多个十六进制的转义序列替换的。

WARNING

请注意 encodeURIComponent() 函数 与 encodeURI() 函数的区别之处,前者假定它的参数是 URI 的一部分(比如协议、主机名、路径或查询字符串)。因此 encodeURIComponent() 函数将转义用于分隔 URI 各个部分的标点符号。

为了避免服务器收到不可预知的请求,对任何用户输入的作为URI部分的内容你都需要用 encodeURIComponent() 进行转义。比如,一个用户可能会输入 Thyme &time=again 作为 comment 变量的一部分。如果不使用 encodeURIComponent() 对此内容进行转义,服务器得到的将是 comment=Thyme%20&time=again 。请注意,& 符号和 = 符号产生了一个新的键值对,所以服务器得到两个键值对(一个键值对是 comment=Thyme ,另一个则是 time=again ),而不是一个键值对。

对于 application/x-www-form-urlencoded (opens new window) (POST) 这种数据方式,空格需要被替换成 +,所以通常使用 encodeURIComponent() 的时候还会把 %20 替换为 +

为了更严格的遵循 RFC 3986 (opens new window)(它保留 ! ' ( ) * ),即使这些字符并没有正式划定 URI 的用途,下面这种方式是比较安全的:

function fixedEncodeURIComponent (str) {
  return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
    return '%' + c.charCodeAt(0).toString(16);
  });
}
1
2
3
4
5

# decodeURIComponent()

操作方式与转义规则和 encodeURIComponent() 一样

// encodeURIComponent() 编码后的参数
const URIstring = 'http%3A%2F%2F127.0.0.1%3A8080%2Fblog%2F%3Fname%3D%E5%85%AD%E5%85%88%E7%94%9F';
decodeURIComponent(URIstring);
// http://127.0.0.1:8080/blog/?name=六先生
1
2
3
4

# 总结

  1. 相同点

    • 都是编码字符串,细微的不同之处在于 escape() 是编码字符串,而 encodeURI()encodeURIComponent() 是编码URI组件
    • 都不会编码 ASCII码的字母、数字
  2. 不同

    • escape()- _ . * @ + /
    • encodeURI()- _ . ! ~ * ' ( ) ; / ? : @ & = + $ , #
    • encodeURIComponent()- _ . ! ~ * ' ( )
  3. 使用场景

    • 如果只是编码字符串,和URI无关,那么用 escape()
    • 如果你需要编码整个URI,然后需要使用这个URI,那么用 encodeURI()
    • 当你需要编码URI中的参数的时候,那么使用 encodeURIComponent()
最近更新: 2024年11月04日 16:53:49