在因特网上传送 URL,只能采用 ASCII 字符集,即是常说的 get 请求只能使用 ASCII 字符。

也就是说 URL 只能使用字母和数字[0-9a-zA-Z]、一些特殊符号$-_.+!*’()[不包括双引号]、以及某些保留字(空格转换为+),才可以不经过编码直接用于 URL。

Javascript 中提供了3对函数用来对 url 编码以得到合法的 url,他们分别是

  • escape / unescape
  • encodeURI / decodeURI
  • encodeURIComponent / decodeURIComponent

这三个编码的函数——escape,encodeURI,encodeURIComponent——都是用于将不安全不合法的 Url 字符转换为合法的Url字符表示,它们有以下几个不同点。

  1. 安全字符不同:
    下面列出了这三个函数的安全字符(即函数不会对这些字符进行编码)

    1
    2
    3
    escape69个):    */@+-._0-9a-zA-Z
    encodeURI82个): !#$&'()*+,/:;=?@-._~0-9a-zA-Z
    encodeURIComponent(71个): !'()*-._~0-9a-zA-Z
  2. 对 Unicode 字符的编码方式不同:
    这三个函数对于 ASCII 字符的编码方式相同,均是使用百分号 + 两位十六进制字符来表示。但是对于 Unicode 字符,escape 的编码方式是 %uxxxx,其中的 xxxx 是用来表示 unicode 字符的4位十六进制字符。这种方式已经被 W3C 废弃了。但是在 ECMA-262 标准中仍然保留着 escape 的这种编码语法。encodeURI 和 encodeURIComponent 则使用UTF-8 对非 ASCII 字符进行编码,然后再进行百分号编码。这是 RFC 推荐的。因此建议尽可能的使用 encodeURI 和 encodeURIComponent 这两个函数替代 escape 进行编码。

  3. 适用场合不同:
    encodeURI 被用作对一个完整的 URI 进行编码,而 encodeURIComponent 被用作对URI的一个组件进行编码。从上面提到的安全字符范围表格来看,我们会发现,encodeURIComponent 编码的字符范围要比 encodeURI 的大。

encodeURI():

  • encodeURI() 是 Javascript中真正用来对 URL 编码的函数。
    它着眼于对整个URL进行编码,因此除了常见的符号以外,对其他一些在网址中有特殊含义的符号”; / ? : @ & = + $ , #”,也不进行编码。编码后,它输出符号的 utf-8 形式,并且在每个字节前加上%。

encodeURIComponent()

  • 它用于对 URL 的组成部分进行个别编码,而不用于对整个 URL 进行编码。
    因此,”; / ? : @ & = + $ , #”,这些在 encodeURI() 中不被编码的符号,在encodeURIComponent()中统统会被编码。至于具体的编码方法,两者是一样。

encodeURIComponent() 和 encodeURI() 的区别演示:

1
2
console.log(encodeURI("?name=zhangsan&age=21"))
console.log(encodeURIComponent("?name=zhangsan&age=21"))

Image text

总结:

开发中大部分情况下使用 encodeURI / decodeURI 和 encodeURIComponent / decodeURIComponent 完全可以了