encodeURI、encodeComponent、decodeURI、decodeURIComponent

最近项目在处理sso问题,需要重定向。这时候用到了encodeURIComponent,突然意识到对这个api不甚了解。特此学习一番。

encodeURIencodeURIComponent都是对URI进行编码的方法。

区别:

  1. 输入参数不同:encodeURI输入的参数是一个完整的URI,encodeURIComponent的输入参数URI的组成部分。
  2. 对字符的处理不同,这个见下面的图
  3. 使用场景不同

一张图解释四个函数对不同字符的处理

字符分类

当URI里包含一个没在上面列出的字符或有时不想让给定的保留字符有特殊意义,那么必须编码这个字符。字符被转换成UTF-8编码,首先从UTF-16转换成相应的代码点值的替代。然后返回的字节序列转换为一个字符串,每个字节用一个“%xx”形式的转移序列表示。

使用场景的不同

encodeURI不会对&, +, =编码,而这三个在GET和POST请求中是特殊字符,所以如果一个URI要进行HTTP的GET和POST请求,不适合使用encodeURI进行编码,而encodeURIComponent则可以。

举个例子:

一个URI是:http://0.0.0.0?comment=Thyme &time=again,本意是comment是变量,值是Thyme &time=again, 如果不使用encodeURIComponent(或者使用encodeURI编码),服务器得到的是http://0.0.0.0?comment=Thyme%20&time=again,此时服务器会解析为两个键值对,comment=Thymetime=again

而如果使用encodeURIComponent对参数进行编码,encodeURIComponent得到的是%3Fcomment%3DThyme%20%26time%3Dagain

注意事项

  1. 为了避免上面说的那种场景,因此,为了避免服务器收到不可预知的请求,对用户输入的URI部分的内容你都需要用encodeURIComponent进行转义。

  2. encodeURIencodeURIComponent如果编码一个非高-低位完整的代理字符,将会抛出一个URIError错误。比如:

1
2
3
4
5
6
7
8
// 高低位完整
alert(encodeURIComponent('\uD800\uDFFF'));

// 只有高位,将抛出"URIError: malformed URI sequence"
alert(encodeURIComponent('\uD800'));

// 只有低位,将抛出"URIError: malformed URI sequence"
alert(encodeURIComponent('\uDFFF'));

因此,为了防止报错影响程序运行,可以使用try/catch包裹:

1
2
3
4
5
6
7
function encodeURIFixed() {
try {
encodeURIComponent()
} catch() {

}
}

参考链接

MDN-encodeURIComponent

一张图看懂encodeURI、encodeURIComponent、decodeURI、decodeURIComponent的区别