一、为什么要进行URI编码
1.路径中含有中文
http://hi.baidu.com/%BE%B2%D0%C4%C0%CF%C8%CB/creat/blog/
2.影响参数解析
参数值中包含=或者&这样的特殊子字符
- POST方式提交 不需要转
- GET方式 链接传值 建议都要转
3.json格式的数据向后台传输时,防止被截断
- RFC3986文档规定:URL中只允许包含英文字母(a-zA-Z)、数字(0-9)、- _ . ~4个特殊字符以及所有的保留字符。
- US-ASCII字符集中没有对应的可打印字符:URL中只允许使用可打印的字符。US-ASCII码中的10-7F字节全都表示控制字符,这些字符不能直接出现在URL中。同时对于80-FF字节,由于已经超出了ASCII码定义字符的范围,因此也不能放在URL中。
- 保留字符:RUL可以划分为干了组件,协议、主机、路径等。有一些字符(: / ? # [ ] @)是用作分隔不同组件的。例如:冒号用于分隔协议和主机组件,斜杠用于分隔主机和路径,问号用于分隔路径和查询参数,等等。还有一些字符(! $ & * + , ; =)用于在每个组件中起到分隔作用,如等号用于表示查询参数中的键值对,&符号用于分隔查询多个键值对。当组件中的普通数据包含这些特殊字符时,需要对其进行编码。
- RFC3986中指定了以下字符为保留字符: ! * ’ ( ) ; : @ & = + $ , / ? # [ ]
- 不安全字符:还有一些字符,当他们直接放在URL中的时候,可能会引起解析程序的歧义。这些字符被视为不安全的字符,原因有很多。
二、js常用的三组编解码方法
只有 0-9[a-Z] $ - _ . + ! * ’ ( ) , 以及某些保留字,才能不经过编码直接用于 URL。
例如:搜索的中文关键字,复制网址之后再粘贴就会发现该URL已经被转码。
原理 | 编码 | 解码 | 不编码字符 | 个数 | |
---|---|---|---|---|---|
escape 和 unescape | 对除ASCII字母、数字、标点符号 @ * _ + - . / 以外的其他字符进行编码 | http%3A// | http:// | *,+,-,.,/,@,_,0-9,a-z,A-Z | 69 |
encodeURI 和 decodeURI | 返回编码为有效的统一资源标识符 (URI) 的字符串,不会被编码的字符:! @ # $ & * ( ) = : / ; ? + ’ encodeURI()是Javascript中真正用来对URL编码的函数。 | http%3A// | http:// | !,#,$,&,’,(,),*,+,,,-,.,/,:,;,=,?,@,_,~,0-9,a-z,A-Z | 82 |
encodeURIComponent 和 decodeURIComponent | 该方法不会对 ASCII 字母和数字进行编码,也不会对这些 ASCII 标点符号进行编码: - _ . ! ~ * ’ ( ) | http%3A%2F%2F | http:// | !, ',(,),*,-,.,_,~,0-9,a-z,A-Z | 71 |
escape
基本淘汰,encodeURI
和encodeURIComponent
比较常用
- escape()除了 ASCII 字母、数字和特定的符号外,对传进来的字符串全部进行转义编码,因此如果想对URL编码,最好不要使用此方法。而encodeURI() 用于编码整个URI,因为URI中的合法字符都不会被编码转换。encodeURIComponent方法在编码单个URIComponent(指请求参数)应当是最常用的,它可以讲参数中的中文、特殊字符进行转义,而不会影响整个URL。
- 请注意 encodeURIComponent() 函数 与 encodeURI() 函数的区别之处,前者假定它的参数是 URI 的一部分(比如协议、主机名、路径或查询字符串)。因此 encodeURIComponent() 函数将转义用于分隔 URI 各个部分的标点符号。
三、拓展阅读
- URL,Uniform Resource Locator,统一资源定位符。用于表示网络上服务器的资源所在位置,比如我们输入浏览器的地址。
- URI,Uniform Resource Identifier,统一资源标识符。它唯一标识了资源。资源的位置能从地址上标识一个资源,所以,URI一种表现形式是URL,URI还有其他表现形式。