最近测试MM反映查看Log的时候会在有些请求中看到“+”,但是最后的结果却没有问题。当时感觉很诡异,走读代码定位发现是因为调用了java.net.URLEncoder的方法出现。后来研究发现才发现没这么简单啊。
`
代码片段:
String tempString = "Hello, World!";
String temStringAfterEncode = "";
try {
temStringAfterEncode = java.net.URLEncoder.encode(tempString,"UTF-8");
} catch (java.io.UnsupportedEncodingException e) {
Log.i("UrlDemo", "bad encoding type");
}
Log.i("UrlDemo", tempString);
Log.i("UrlDemo", temStringAfterEncode);
android.net.Uri.encode(tempString);
Log.i("UrlDemo", tempString);
Log.i("UrlDemo", temStringAfterEncode);
结果如下:
07-21 11:47:28.695: I/UrlDemo(1222): Hello, World!
07-21 11:47:28.695: I/UrlDemo(1222): Hello%2C+World%21
07-21 11:47:28.705: I/UrlDemo(1222): Hello, World!
07-21 11:47:28.705: I/UrlDemo(1222): Hello%2C+World%21
`
走读代码发现java将’ ‘转成了’+’。由于之前做过比较久web前端,映像中URL编码规则应该是将空格转为%20。上网看了下,又貌似都是对的,决定试一试。先用站长工具测试了一下URL Encode(如下图),瞬间晕倒,竟然‘+’才是主流的。
地址: https://tool.chinaz.com/Tools/URLEncode.aspx 编码结果:
仍不死心,继续用php测试一番。
`
代码片段:
$tempString = "Hello, World!";
$temStringAfterEncode = urlencode($tempString);
echo $tempString ."\n".$temStringAfterEncode."\n";
执行结果:
$ /usr/bin/php ./urlDemo.php
Hello, World!
Hello%2C+World%21
·
再次崩溃,是谁伤害了我?
最后用JS试一下:
好吧,原来是JS坑了我,罪魁祸首是JS,这到底是为什么呢?
‘ ’确实是被 ‘+’替代,他使用的编码标准为RFC-1738。
Encodes characters in the given string as'%'-escaped octets using the UTF-8 scheme. Leaves letters ("A-Z","a-z"), numbers ("0-9"), and unreserved characters("_-!.~'()*") intact. Encodes all other characters.
###在HTML4.0.1中,基于RFC-1738标准,‘ ’在URL编码以后为 ‘+’,只有JS中由于基于RFC-2396标准,‘ ’在URL编码以后为‘%20’。
最后推荐一个MSDK开发使用的encode函数:
/**
* URL encode推荐方法
* @param value
* @return
*/
public static String encode(String value) {
String encoded = "";
try {
encoded = URLEncoder.encode(value, "UTF-8");
} catch (UnsupportedEncodingException ignore) {
}
StringBuffer buf = new StringBuffer(encoded.length());
char focus;
for (int i = 0; i < encoded.length(); i++) {
focus = encoded.charAt(i);
if (focus == '*') {
buf.append("%2A");
} else if (focus == '+') {
buf.append("%20");
} else if (focus == '%' && (i + 1) < encoded.length()
&& encoded.charAt(i + 1) == '7'
&& encoded.charAt(i + 2) == 'E') {
buf.append('~');
i += 2;
} else {
buf.append(focus);
}
}
return buf.toString();
}