一、为什么要把url编码
URL通俗来说就是网址,只要上网,就一定会用到。
我们在浏览器中输入url,同时通过表单或ajax提交一些字段内容时,所有的输入,最终肯定是由浏览器或者操作系统做统一解析,获取远程网站地址,获取提交内容,然后将数据封装成二进制传给远程网站。那么浏览器要解析url,url就必须要有一个标准的格式和一个标准的编码。 标准的格式就像http://www.hostname.com/path/index.php?r=xx#,url是要尊重一定的范式,包括scheme,authority,path,query,fragment。 标准的编码当然就是ASCII码,(毕竟人家发明计算机的时候,肯定不会考虑兼容中文,德文,日语之类的,所有的编码采用ASCII码是最简单的)。 那么我们在使用url的时候,url不能包含任何非ASCII字符,例如中文。而且有些ASCII字符也是不安全的字符,可能会引起url语义解析问题,所以最终必须要对url编码。编码的原则就是使用安全的字符(没有特殊用途或者特殊意义的可打印字符)去表示那些不安全的字符。二、url编码的目标
url中只能出现的字符
url中的保留字符
url可以划分成若干个组件,协议、主机、路径等。有一些字符是用作分隔组件的。例如:用于分隔协议和主机,/用于分隔主机和路径,?用于分隔路径和查询参数等等。还有一些字符用于在每个组件中起分隔作用,例如=用于表示查询参数中的键值对,&用于分隔多个键值对。 当组件中的普通数据包含这些特殊字符的时候,也需要对数据进行编码。url中的不安全字符
还有一些字符,当他们直接放在url中的时候,可能会引起解析程序的歧义。这些字符被视为不安全字符。对于url中的合法字符,编码和不编码是等价的,但是对于不安全的字符,如果不经过编码,可能会造成语义的不同。
三、url编码的方式
url编码通常被称为百分号编码,就是因为他的编码方式是使用%加上两位16进制字符。
对于ASCII字符进行编码就是取ASCII码中对应的字节,前面加上% 常见字符的url编码列表: 对于非ASCII字符,使用ASCII字符集的超集进行编码得到相应的字节,然后对每个字节执行百分号编码。对于unicode字符,RFC文档建议使用utf-8编码得到相应的字节。如”中文“使用utf-8字符集编码得到的字节为0xE4 0xB8 0xAD 0xE6 0x96 0x87,经过Url编码之后得到“%E4%B8%AD%E6%96%87”。JavaScript中提供了三个函数对url进行编码。
1.escape 2.encodeURI 3.encodeURIComponent 三者的区别是:安全字符不同
兼容性不同
escape函数是从Javascript1.0的时候就存在了,其他两个函数是在Javascript1.5才引入的。但是由于Javascript1.5已经非常普及了,所以实际上使用encodeURI和encodeURIComponent并不会有什么兼容性问题。
对Unicode字符的编码方式不同
这三个函数对于ASCII字符的编码方式相同,均是使用百分号+两位十六进制字符来表示。但是对于Unicode字符,escape的编码方式是%uxxxx,其中的xxxx是用来表示unicode字符的4位十六进制字符。这种方式已经被W3C废弃了。但是在ECMA-262标准中仍然保留着escape的这种编码语法。encodeURI和encodeURIComponent则使用UTF-8对非ASCII字符进行编码,然后再进行百分号编码。这是RFC推荐的。因此建议尽可能的使用这两个函数替代escape进行编码。
适用场合不同
encodeURI用作对一个完成的URI进行编码,而encodeURIComponent用作对URI的一个组件进行编码。前者由于操作的是完整的uri,而在完整uri中一些保留字符如:=?等是有特殊用途的,因此不对这些字符进行编码。
后者在对组件内部数据进行编码是,考虑到内部数据可能会重用保留字符,可能对整个uri造成混乱,因此要进行编码的字符范围要更大。参考资料: