URL(Uniform Resource Locator)统一资源定位符,是 URI(Uniform Resource Identifiers)的一种。

URL中参数使用key=value键值对表示,键值对之间以&符号分隔,如/abc?x=1&y=2。如果key或value字符串中包含了=或&,那么就会造成接收URL的服务器解析错误,因此必须对&和=符号进行转义,也就是编码。编码的原则就是使用安全的字符去表示那些不安全的字符。

编码规则

URL根据 RFC 3986 中的规则进行编码。

URL编码通常也被称为百分号编码(percent-encoding),因为编码是使用%百分号加两位十六进制字符(代表一个字节)的形式。URL的编码格式采用的是ASCII码,即URL中不能包含任何非ASCII字符,URL编码默认使用的字符集是US-ASCII。例如@符号在ASCII字符集中对应的字节为0x40,URL编码之后是%40。对于Unicode字符,使用UTF-8对其进行编码得到相应的字节,然后对每个字节执行百分号编码,例如"汉"使用UTF-8字符集得到的字节为0xE6 0xB1 0x89,经过URL编码之后得到"%E6%B1%89"。

RFC3986文档规定,URL中只允许包含英文字母(a-zA-Z)、数字(0-9)、-_.~4个特殊字符以及所有保留字符。

保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ]

不安全字符:一些字符,当他们直接放在URL中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符。

JavaScript编码实现

Javascript提供了3对URL编码函数:escape/unescape, encodeURI/decodeURI和encodeURIComponent/decodeURIComponent,解码和编码的过程是可逆的。

差异有:

其他

当html的表单被提交时,每个表单都会被URL编码。由于历史的原因,表单使用的URL编码实现并不符合最新的标准。例如空格使用的编码不是%20,而是+号,可能需要自己实现将+号解码成空格的转换。

对于非ASCII字符,使用的编码字符集取决于当前文档使用的字符集。例如head加上<meta http-equiv="Content-Type" content="text/html; charset=gb2312" /> 这样浏览器就会使用gb2312去渲染此文档(无此设置,则浏览器会根据当前用户偏好去自动选择字符集,用户也可以强制当前网页使用某个指定的字符集)。页面文件存储使用的字符集和meta标签中指定的字符集不一致也会导致问题。比如文件实际存储的时候使用的是UTF-8字符集,但是由于meta标签中指定了gb2312,浏览器就会按照gb2312去解析这个文档。



控制台察看结果