iOS中URL编码那些事
2016-11-27 22:47
176 查看
前言
在iOS程序中,访问一些HTTP/HTTPS的资源服务时,如果url中存在中文或者特殊字符时,会导致无法正常的访问到资源或服务,想要解决这个问题,需要对url进行编码。一、编码的原因和范围
1. 为什么要编码
网络标准RFC 1738规定url中只能包含英文字母和阿拉伯数字,以及一些特殊字符:"...Only alphanumerics [0-9a-zA-Z], the special characters "$-_.+!*'()," [not including the quotes - ed], and reserved characters used for their reserved purposes may be used unencoded within a URL."
“只有字母和数字[0-9a-zA-Z]、和特殊符号”$-_.+!*’(),”[不包括双引号]、及某些保留字,才可以不经过编码直接用于URL。”
此时如果url中包含如汉字或者其他特殊字符则需要对它进行编码,编码的意义在于,假如url的参数中的中文或特殊字符在发送到服务端时,服务端无法解析它的真正意义,会导致服务端不能理解客户端的请求。
如:
url中的保留字
?表示后面连接的是一些请求参数,而参数中如果也包含
?,服务端就不知道从哪个
?之后是参数;
url中的保留字
&用来连接并列的参数项,参数中包含
&时,服务端依然无法判断。
2. 转码范围
ASCII 的控制字符这些字符都是不可打印的,自然需要进行转化。
一些非ASCII字符
这些字符自然是非法的字符范围。转化也是理所当然的了。
一些保留字符
很明显最常见的就是“&”了,这个如果出现在url中了,那你认为是url中的一个字符呢,还是特殊的参数分割用的呢?
就是一些不安全的字符了。
例如:空格。为了防止引起歧义,需要被转化为“+”。
二、编码实现
1. 使用CoreFoundation
对url参数
进行encode
使用到的APICFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding)
代码示例:
- (void)encodeUrl { // p1=%+&sd NSString *para1 = [self encodeParameter:@"%+&sd"]; // p2=我是参数2 NSString *para2 = [self encodeParameter:@"我是参数2"]; NSString *encodeUrl = [NSString stringWithFormat:@"https://www.xingshulin.com?p1=%@&p2=%@", para1, para2]; NSLog(@"%@", encodeUrl); } - (NSString *)encodeParameter:(NSString *)originalPara { CFStringRef encodeParaCf = CFURLCreateStringByAddingPercentEscapes(NULL, (__bridge CFStringRef)originalPara, NULL, CFSTR("!*'();:@&=+$,/?%#[]"), kCFStringEncodingUTF8); NSString *encodePara = (__bridge NSString *)(encodeParaCf); CFRelease(encodeParaCf); return encodePara; }
编码结果:
https://www.xingshulin.com?p1=%25%2B%26sd&p2=%E6%88%91%E6%98%AF%E5%8F%82%E6%95%B02
可以看到转码对象中,除了中文正常转码外,特殊字符只要包含在
!*'();:@&=+$,/?%#[]这些字符范围内的都进行了转码。
注意:
此方法适用于,url前缀不包含中文以及其它非法字符的情况,只需要对参数进行编码即可。
2. 使用Foundation
框架对完整url
进行encode
方法1:(不推荐)使用到的API
- (nullable NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc
代码示例:
NSString *originalUrl = @"https://www.xingshulin.com我是中文?p1=abc&p2=我是参数2"; NSString *encodeUrl = [originalUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; NSLog(@"%@", encodeUrl);
编码结果:
https://www.xingshulin.com%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87?p1=abc&p2=%E6%88%91%E6%98%AF%E5%8F%82%E6%95%B02
可以看到转码对象中,除了中文正常转码外,特殊字符只要包含在
!*'();:@&=+$,/?%#[]这些字符范围内的都进行了转码。
注意:
此方法适用于url或者参数中包含中文以及其它非法字符的情况,但不适用于参数包含保留字和其他特殊字符的情况。
方法2:(推荐)
使用到的API
- (nullable NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters
代码示例:
NSString *originalUrl = @"https://www.xingshulin.com我是中文?p1=abc&p2=我是参数2"; NSCharacterSet *encodeUrlSet = [NSCharacterSet URLQueryAllowedCharacterSet]; NSString *encodeUrl = [originalUrl stringByAddingPercentEncodingWithAllowedCharacters:encodeUrlSet]; NSLog(@"%@", encodeUrl);
编码结果:
https://www.xingshulin.com%E6%88%91%E6%98%AF%E4%B8%AD%E6%96%87?p1=abc&p2=%E6%88%91%E6%98%AF%E5%8F%82%E6%95%B02
可以看到转码对象中,除了中文正常转码外,特殊字符只要包含在
!*'();:@&=+$,/?%#[]这些字符范围内的都进行了转码。
注意:
与方法1相同。
对比
之所以推荐
方法2,是由于
方法1已经在iOS9中被苹果废弃,而且1支持的字符比较少,只对
`#%^{}[]|\"<> 加空格共14个字符编码,不包括
&?等符号。
三、拓展:stringByAddingPercentEncodingWithAllowedCharacters
用法
stringByAddingPercentEncodingWithAllowedCharacters接收
NSCharacterSet对象,几种常用的
NSCharacterSet:
URLFragmentAllowedCharacterSet "#%<>[\]^`{|} URLHostAllowedCharacterSet "#%/<>?@\^`{|} URLPasswordAllowedCharacterSet "#%/:<>?@[\]^`{|} URLPathAllowedCharacterSet "#%;<>?[\]^`{|} URLQueryAllowedCharacterSet "#%<>[\]^`{|} URLUserAllowedCharacterSet "#%/:<>?@[\]^`
参考:
rfc1738
关于URL编码
为什么要对url进行encode
url出现特殊字符处理– stringByAddingPercentEncodingWithAllowedCharacters
NSCharacterSet
相关文章推荐
- ios那些事之如何在ios5上运行gdb
- [Cocoa]iOS中的url编码问题
- iOS开发那些事--编写OCUnit测试方法-应用测试方法
- iOS开发那些事--nib、xib与故事板的关系
- iOS开发那些事--iOS视图生命周期与视图控制器关系
- iOS开发那些事--iOS6 UI状态保持和恢复
- iOS开发那些事--创建基于nib的iOS 6的HelloWorld工程
- iOS开发那些事--创建基于nib的iOS 6的HelloWorld工程
- iOS开发那些事--nib、xib与故事板的关系
- 涉足iOS开发的那些事
- iOS中的url编码问题
- iOS开发那些事--编写OCUnit测试方法-逻辑测试方法
- iOS开发那些事--编写OCUnit测试方法-应用测试方法 推荐
- iOS开发那些事--OCUnit测试框架
- 【游戏设计】游戏设计师修炼秘籍 读书笔记二(讲IOS的那些事)
- 这些天,折腾ios的那些事
- 关于申请IOS开发者账号到APPStore上架的那些事
- iOS开发那些事--创建基于nib的iOS 6的HelloWorld工程 推荐
- iOS开发那些事--iOS6 UI状态保持和恢复
- iOS开发那些事--iOS视图生命周期与视图控制器关系 推荐