Blog
Blog copied to clipboard
URI编码的两方法异同与场景
encodeURI
这里先单纯介绍该函数的语法规则,场景后续说。先说作为一个函数,它能做什么。
它是全局对象下的方法,在浏览器器客户端里就是window
对象的方法。它的作用是,对字符串的每个字符进行UTF-8编码,使用一到四个转义序列来表示。参数为要编码的字符串,返回值为编码后的字符串结果。
window.encodeURI(str)
编码的规则是:
除以下字符外,其余字符都进行编码
-
;,/?:@&=+$
(此为URL的特殊字符) -
#
(数字标识) - 字母和数字
-
-_.!~*'()
(保留的字符)
编码实际上是将每个字符先进行UTF-8编码,用16进制表示码值,然后在前面追加%来表示。如
encodeURI('我')
// 返回值为
// %E6%88%91
先将“我”进行UTF-8编码后由0xE6、0x88、0x91三个字节来表示,然后每个字节前面加%,就变成了%E6%88%91
有编码自然有解码,对应的解码方法是decodeURI
encodeURIComponent
这里先单纯介绍该函数的语法规则,场景后续说。先说作为一个函数,它能做什么。
它是全局对象下的方法,在浏览器器客户端里就是window
对象的方法。它的作用是,对字符串的每个字符进行UTF-8编码,使用一到四个转义序列来表示。参数为要编码的字符串,返回值为编码后的字符串结果。
window.encodeURIComponent(str)
编码的规则是:
除以下字符外,其余字符都进行编码
- 字母和数字
-
-_.!~*'()
(保留的字符)
编码实际上是将每个字符先进行UTF-8编码,用16进制表示码值,然后在前面追加%来表示。如
encodeURI('我')
// 返回值为
// %E6%88%91
先将“我”进行UTF-8编码后由0xE6、0x88、0x91三个字节来表示,然后每个字节前面加%,就变成了%E6%88%91
有编码自然有解码,对应的解码方法是decodeURIComponent
二者的异同
由上面两节内容就可以看到,他们很相似,都是对字符串进行编码,唯一的差别就是,他们的编码规则不一样,可以看出他们的能力范围不同
- 二者都对字母和数字以及
-_.!~*'()
不会进行编码 - 但
encodeURI
还会对别的一些保留字符不会进行编码,即它所能编码的字符比encodeURIComponent
要少。
用下面的实例一目了然:
var set1 = ";,/?:@&=+$"; // url特殊字符
var set2 = "-_.!~*'()"; // 保留的一些字符
var set3 = "#"; // 数字标识
var set4 = "ABC abc 123"; // 字母和数字,这里还有空格字符
console.log(encodeURI(set1)); // ;,/?:@&=+$
console.log(encodeURI(set2)); // -_.!~*'()
console.log(encodeURI(set3)); // #
console.log(encodeURI(set4)); // ABC%20abc%20123 (the space gets encoded as %20)
console.log(encodeURIComponent(set1)); // %3B%2C%2F%3F%3A%40%26%3D%2B%24
console.log(encodeURIComponent(set2)); // -_.!~*'()
console.log(encodeURIComponent(set3)); // %23
console.log(encodeURIComponent(set4)); // ABC%20abc%20123 (the space gets encoded as %20)
使用场景
正所谓“存在即有理”,当初发明出这两个函数,当然是有目的,即有使用场景的,至于现实中是不是仅仅用在发明者预想的使用场景中,就另当别论了。毕竟工具无情,使用者有情。
encodeURI
被发明出来时,就预想着是用来解决这样的问题的:
一个URI,作为能够在互联网被访问,是有它自身的组成规则的(如协议名+域名+端口号,以及它本身所提供的特殊字符),这些在规则内的字符,不会受到不同操作系统和浏览器的影响,都是会被识别成同一个URI。但是一个URI的组成,可能会存在这些规则外的字符(如在URL的查询部分中,可出现各种字符),那么这些字符可能会受到操作系统或浏览器的不同而被解析成不同的内容,导致这个URI不能被识别为唯一的,如用户在操作系统A中和在操作系统B中访问这个URI,得到的结果却是不一样的。
因此为了避免发生上述情况,可对这整个URI进行编码,让其不论在何种背景下,都能识别成唯一的URI,因此,encodeURI
就诞生了。
所以encodeURI
主要是用来对整个URI进行编码的。
encodeURIComponent
被发明出来时,就预想着是用来解决这样的问题的:
URI的查询部分,如在组成键值对时,有些值可能会用到URI保留的特殊字符,如果直接这么访问的话,会出现歧义,如
?text=piano&football=1
,就这么一段查询部分,你的初衷是想把piano&football=1
当做是text
的值,但是如果不做处理的话,浏览器会识别成两个键值对,分别是text=piano
和football=1
。
因此为了避免发生上述误解,我们需要对这部分查询进行编码,让其表示为一个整体值
var textValue = encodeURIComponent(piano&football=1)
编码后再拼接回原来的URI字符串里
'?text=' + textValue
因为这种URI保留的特殊字符,encodeURI
是不会对其进行编码的,因此需要用到encodeURIComponent
所以encodeURIComponent
主要是用来对URI的组成部分进行编码的。
切记,千万别把整个URI使用encodeURIComponent
进行编码,不然由于URI的保留特殊字符被编码了,导致URI不可被访问了或访问结果未能预期所想。
by the way, escape
方法已被废弃了,不建议使用。