php中urlencode、rawurlencode,javascript中encodeURI、encodeURIComponent

在项目中,常常需要对url、uri进行编码和解码,数据也要编码后进行传输,因此,本文要讲的内容就非常重要。在一些测试中,我们发现,有的时候先进行php的encodeurl编码,然后再进行decodeurl解码,再用到javascript中,结果会发生一些错误。编码到解码,会出现一些差错,这是由于不同的函数依照不同的标准进行编写,所以经过编码,再解码,就可能会出现问题。

PHP中的urlencode和urldecode

urlencode是最传统的url编码函数。特别是在<form>的数据传输中,php在接收表单时,就是以urlencode的结果形式进行接收的,如果<form>的提交形式是get,你就可以在结果地址中看到。但是在php中使用$_GET、$_POST进行接收时,结果却是已经urldecode了的。官方文档的解释是:此编码与 WWW 表单 POST 数据的编码方式是一样的,同时与 application/x-www-form-urlencoded 的媒体类型编码方式一样。

urlencode在编码中文和一些字符时,就是将其转换为对应的十六进制编码。

urldecode在解码时,也有GB2312和UTF-8之分,主要是用在不同的搜索引擎中,谷歌雅虎使用的是UTF-8,而百度则使用的是GB2312。如何在GB2312和UTF-8之间转换呢?主要用到mb_convert_encoding函数,具体这里就不赘述。

中文 -> GB2312的Encode -> %D6%D0%CE%C4
中文 -> UTF-8的Encode -> %E4%B8%AD%E6%96%87

PHP中的rawurlencode和rawurldecode,及与urlencode的比较

urlencode虽然主要用在数据提交和传输过程中,但是如果在构造url时,rawurlencode更好。rawurlencode和encode的区别,主要是这两个函数编写时依据的标准不一样rawurlencode采用的是RFC1738 编码,主要区别在于,对一些特殊字符的编码结果不同,rawurlencode对更多的字符采用十六进制编码,特别是空格,urlencode编码空格后是加号+,而rawurlencode编码空格后是%20.

urlencode(' ') => +
rawurlencode(' ') => %20

官方文档中指出,对~不再进行编码了。

Javascript中的encodeURI和decodeURI

rawurlencode遵守是94年国际标准备忘录RFC1738,而Javascript中的encodeURI也遵循该标准,所以从某种意义上,php的rawurlencode的编码结果和Javascript的encodeURI的编码结果是一样的。

encodeURI不编码字符有82个:!#$&'()*+,-./:;=?@_~0-9a-zA-Z

Javascript中的encodeURIComponent和decodeURIComponent

encodeURIComponent的意思非常明确,就是要对uri的组成部分进行编码,我们用下面的例子来解释。

/test-url/测试.html

其中test-url测试.html这两个段就是component,如果要进行编码,就应该用encodeURIComponent。但是如果你用encodeURIComponent('/test-url/测试.html')进行编码,就会对'/'也进行编码,整个URI会变成编码后的十六进制字符串。而encodeURI进行编码时,则不会对'/'进行编码,还是完整的URI,只不过对uri component进行了编码。

encodeURIComponent不编码字符有71个:!'()*-._~0-9a-zA-Z

缺少了:#$&+,/:;=@

故此,实际上,在Javascript的体系里,如果要对数据进行传输,要么不进行编码,要么使用encodeURIComponent编码,再进行传输,这样才能让数据解码后不变样。

2015-04-07