URI
URI是统一资源标识的意思,通常我们所说的URL只是URI的一种。典型URL的格式如下所示。下面提到的URL编码,实际上应该指的是URI编码。***
foo://example.com:8042/over/there?name=ferret#nose
scheme authority path query fragment
避免歧义
HTTP协议中参数组件的传输是“key=value”键值对的形式,如果要传输多个参数就需要用“&”符号对键值对进行分隔。例如
?name1=value1&name2=$value2
,这样在服务器收到这种字符串的时候,会用“&”分隔出每一个参数,然后再用“=”来分隔出参数值。如果我的参数值中就包含=或者&这样的特殊子字符的时候,该怎么办。比如说“name1=value1”,其中value1的值是“va&lu=e1”,那么在传输过程中就会变成“name1=va&lu=e1”。用户传输的本意是只有一个键值对,但是服务器端会解析成两个键值对,这样就自然的产生了歧义。
解决方法
JavaScript中提供了3对函数用来对Url编码以得到合法的Url,它们分别是
escape / unescape,
encodeURI / decodeURI
encodeURIComponent / decodeURIComponent
由于解码和编码的过程是可逆的,因此这里只解释编码的过程。
这三个编码的函数——escape,encodeURI,encodeURIComponent——都是用于将不安全不合法的Url字符转换为合法的Url字符表示,它们有以下几个不同点。
下面列出了这三个函数的安全字符(即函数不会对这些字符进行编码)
escape(69个):*/@±._0-9a-zA-Z
encodeURI(82个):!#$&’()*+,/:;=?@-._~0-9a-zA-Z
encodeURIComponent(71个):!’()*-._~0-9a-zA-Z
encodeURIComponent("http://baidu.com")
"http%3A%2F%2Fbaidu.com"
decodeURIComponent("http%3A%2F%2Fbaidu.com")
"http://baidu.com"
encodeURIComponent("我是中文")
"%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87"
decodeURIComponent("%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87")
"我是中文"
encodeURIComponent("@")
"%40"
encodeURI("@")
"@"