问题:当我提交一个时间2021-09-09 12:30给接口,服务器日志打印的日志确变成了2021-09-09+12:30。
想到工程中有个POST参数处理逻辑,提交参数的时候需要将空格替换成加号,搜索一下,这个问题由来已久大神讲得比较明白。
寻思着将这段代码去掉,结果签名不通过,查看了一下生成签名及提交过程。
客户端逻辑
1.将2021-09-09 12:30进行URLEncode生成2021-09-09%2012:30。
2.然后md5(2021-09-09%2012:30)得到签名sign。
3.再把2021-09-09%2012:30和sign的值提给接口。
服务端逻辑
1.将2021-09-09%2012:30进行url.QueryUnescape得到2021-09-09 12:30。
2.再将2021-09-09 12:30进行url.QueryEscape得到2021-09-09+12%3A30。
3.然后md5(2021-09-09+12%3A30)得到签名sign。
结论:对比后签名不通过原因就是url.QueryEscape在空格替换成加号了。
最开始我在想不必要将所有的参数都处理空格换成加号,其实还是需要的,因为服务端接收到的所有参数都经过了url.QueryUnescape处理,其实最根本的原因是urlcode编码不一样(逻辑有点绕)。
iOS要达到和Android同样的效果有两点:
1.字符串中每个字符要单独判断。
2.如循环取出的一个字是空格,就替换成加号。
3.如循环取出的一个字是不是空格,就要进行编码。
最后帖上swfit5的最新写法:
func escape(_ string: String) -> String {
var str = ""
var set = NSCharacterSet.urlQueryAllowed
set.remove(charactersIn: "!*'\"();:@&=+$,/?%#[]% ")
for char in string {
if char == " " {
str += "+"
} else {
str += (String(char).addingPercentEncoding(withAllowedCharacters: set) ?? String(char))
}
}
return str
}