url中如果带有特殊字符,正常处理一般都是urlencode,但对于空格,会有些特别奇葩的情况。
-
PHP
先看一下php的处理:
<?php
$url = 'http://www.abc.com/apple iphone+ipad';
$encode_url = urlencode($url);
echo 'encode_url:'.$encode_url.PHP_EOL;
$decode_url = urldecode($encode_url);
echo 'decode_url:'.$decode_url.PHP_EOL;
?>
输出:
encode_url:http%3A%2F%2Fwww.abc.com%2Fapple+iphone%2Bipad
decode_url:http://www.abc.com/apple iphone+ipad
可以看到字符串中的空格urlencode后变成了+加号。
-
golang
golang提供了两种escape标准实现方法,区别在于
url.PathEscape:空格会转为 %20
url.QueryEscape:空格会转为 +
url.Values.Encode:内部是QueryEscape
看下效果:
PathEscape:
var str string = "http://www.abc.com/apple iphone+ipad"
str = url.PathEscape(str)
fmt.Println(str)
str, err := url.PathUnescape(str)
fmt.Println(str)
fmt.Println(err)
输出:
apple%20iphone+ipad
apple iphone+ipad%android
<nil>
QueryEscape:
var str string = "http://www.abc.com/apple iphone+ipad"
str = url.QueryEscape(str)
fmt.Println(str)
str, err := url.QueryUnescape(str)
fmt.Println(str)
fmt.Println(err)
输出:
http%3A%2F%2Fwww.abc.com%2Fapple+iphone%2Bipad
http://www.abc.com/apple iphone+ipad
<nil>
注意点
PathUnescape、QueryUnescape解析不出时会报err,跟php不一样,比如
str := "100%power"
str, err := url.QueryUnescape(str)
fmt.Println(str) //空字符串
fmt.Println(err) //invalid URL escape "%po"
需要判断err不是nil是返回原字符串,不然str会变成空值了
str := "100%power"
if res, err := url.QueryUnescape(str); err == nil {
str = res
}
fmt.Println(str) //100%power
踩坑坑坑坑
当php的urlencode后的字串,在golang中PathUnescape解析时,会出现偏差
str := "http%3A%2F%2Fwww.abc.com%2Fapple+iphone%2Bipad" //php中urlencode后的地址
str, err := url.PathUnescape(str)
fmt.Println(str)
fmt.Println(err)
输出:
http://www.abc.com/apple+iphone+ipad
<nil>
期望值是http://www.abc.com/apple iphone+ipad,结果空格没有解出来
建议
当与php互相传输的数据需要url处理时,建议都使用url.QueryEscape。
某些特殊情况,比如某些验签,需要空格号转为%20再加密时,就会用到url.PathEscape。