首先简单讲解下为什么URL需要编码
服务端解析URL是通过遍历字节流的方式处理
Http协议中参数的传递是通过键值对"key=value"形式来进行,多参数之间使用“&”符号对键值对进行拼接,如:"?key1=value1&key2=value2"。而服务端对URL的解析,也是以“&”分割出每个参数键值对,以“=”分割每个键值对中的键和值,一个字节一个字节对URL字节流进行处理的。
URL编码原理只是在特殊字符的各个字节前加上%
上述的解析会产生一个问题:如果参数的值本身就带有“&”,“=”这种特殊字符怎么办?这就是进行URL编码的原因所在。URL编码原理只是在特殊字符的各个字节前加上%,这里说的特殊字符不仅仅只是“=”和“&”,而且还有保留字符、不安全字符以及非ASCII码字符,下面会详细解析。
URL编码默认使用的字符集是US-ASCII
既然是编码,自然就会用到字符集,就像解析密码需要密码本一样。URL编码默认使用的字符集是US-ASCII,所以对于URL编码,最准确的定义应该是:百分号(%)加上该字节对应的两位US-ASCII字符(由0123456789ABCDEF组成,代表该字节的十六进制形式)。那么,什么情况下需要对字节进行编码呢,还是说所有字节都需要编码?对于URL中的合法字符,编码和不编码是等价的,也就是说,假如参数为:key1=url,这种情况下编码与不编码是一样的,进而言之,只有对保留字符、不安全字符以及非ASCII码字符进行的URL编码才有实际的意义。
- 保留字符:RFC3986(Uniform Resource Identifier规范文档,参考 https://www.rfc-editor.org/rfc/rfc3986.txt )中指定了以下字符为保留字符:! * ' ( ) ; : @ & = + $ , / ? # [ ],这些字符大多用于分隔不同组件
- 不安全字符:这些字符,直接放在URL的话,可能会引起解析程序的歧义,他们包括空格、引号、<>、#、%、{}、|、\、^、[]、`、~
- 非ASCII码字符:需要使用ASCII字符集的超集进行编码得到相应的字节,然后对每个字节执行百分号编码。值得注意的是,RFC文档建议对Unicode字符进行UTF-8编码得到相应的字节,然后对每个字节再进行百分号编码。例如,“编码”使用UTF-8字符集得到的字节为0xE7 0xBC 0x96 0xE7 0xA0 0x81,经过URL编码变成%e7%bc%96%e7%a0%81。但是在实际应用场景中,有些地方是使用GB2312字符集编码,这跟操作系统的语言、甚至是浏览器都有关系,所以也造成URL编码混乱的原因之一。
iOS的URL编码说明
- iOS 7及以上:stringByAddingPercentEncodingWithAllowedCharacters [path stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
- iOS 7以下(iOS 9过期):stringByAddingPercentEscapesUsingEncoding
iOS的URL解码说明
- iOS 7及以上:stringByRemovingPercentEncoding
- iOS 7以下(iOS 9过期):stringByReplacingPercentEscapesUsingEncoding