URL里中文字符正确过滤姿势
今天有个同事跟我反馈,有个复杂参数的路由跳转需求,目前路由解析满足不了。
这个需求是服务推送一个URL scheme到app,又app的路由寻找到对应的页面。
这个URL结构大致如下:
|
|
第一层嵌了一个参数url,第二层url的value里又嵌了一个参数url2。
服务端对这个url做了encode,推送到app的字符串如下:
|
|
在路由里为了避免空格和中文字符,会对传入的url分别调用stringByReplacingPercentEscapesUsingEncoding和stringByAddingPercentEscapesUsingEncoding
|
|
问题来了,因为stringByReplacingPercentEscapesUsingEncoding会对”%3a%2f%3d%26%3f”等被转义的保留字符反转义回”:/=&?”。
而stringByAddingPercentEscapesUsingEncoding只会对中文非法字符做percent转义,不会处理”:/=&?”等保留字符做encode处理。所以最后经过路由后,URL变成如下:
|
|
这就导致第一层的参数url里的链接没有被encode,url2、key3这两个参数都被错认为是第一层的参数了。
路由层做过滤的实际意图是希望,把中文字符转义掉,同时又不影响url各层参数的encode状态。
解决的办法是使用如下两个方法:
|
|
使用以上2个方法,便只会对中文非法字符进行转义,不会影响其他保留字符的转义情况。
多层嵌套url正确的encode姿势
除此之外,对于多层嵌套的url需要正确地encode.
|
|
对于上面例子这个url,需要做2层的urlencode
错误encode方式:
blacktea%3a%2f%2fgotoWebView%3furl%3dhttps%3a%2f%2fm.alibaba.com%3fkey1%3dvalue1%26url2%3dhttps%3a%2f%2fwww.blacktea.com.js%26key3%3dvalue3
正确encode方式:
第一次encode
from:
https://www.blacktea.com.js
to:
https%3a%2f%2fwww.blacktea.com.js
第二次encode
from:
https://m.alibaba.com?key1=value1&url2=https%3a%2f%2fwww.blacktea.com.js&key3=value3
to:
https%3a%2f%2fm.alibaba.com%3fkey1%3dvalue1%26url2%3dhttps%253a%252f%252fwww.blacktea.com.js%26key3%3dvalue3
result:
|
|
客户端拿到这个被多层encode的url后,再一层一层能地解开,没解开一层都要decode一遍。
UrlEncode编码原理
编码原理:
将需要转码的字符转为16进制,然后从右到左,取4位(不足4位直接处理),每2位做一位,前面加上%,编码成%XY格式。
比如:
空格ASCII码是32,对应16进制是20,那么urlencode编码结果是:%20
比如:
中ASCII码是-10544,对应的16进制是FFFFFFFFFFFFD6D0,那么urlencode编码结果是:%D6%D0
URI统一资源标识符里允许的所有字符里,分为保留字符和非保留字符。百分号编码(Percent-encoding)会把保留字符转义为特殊字符序列。
百度百科urlencode