前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS中URL编码那些事

iOS中URL编码那些事

作者头像
freesan44
发布2018-09-05 16:00:41
2.5K0
发布2018-09-05 16:00:41
举报
文章被收录于专栏:freesan44freesan44

前言

在iOS程序中,访问一些HTTP/HTTPS的资源服务时,如果url中存在中文或者特殊字符时,会导致无法正常的访问到资源或服务,想要解决这个问题,需要对url进行编码。

一、编码的原因和范围

1. 为什么要编码

网络标准RFC 1738规定url中只能包含英文字母和阿拉伯数字,以及一些特殊字符:

代码语言:javascript
复制
"...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. 使用CoreFoundationurl参数进行encode

使用到的API

代码语言:javascript
复制
CFStringRef CFURLCreateStringByAddingPercentEscapes(CFAllocatorRef allocator, CFStringRef originalString, CFStringRef charactersToLeaveUnescaped, CFStringRef legalURLCharactersToBeEscaped, CFStringEncoding encoding)

代码示例:

代码语言:javascript
复制
- (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;
}

编码结果:

代码语言:javascript
复制
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

代码语言:javascript
复制
- (nullable NSString *)stringByAddingPercentEscapesUsingEncoding:(NSStringEncoding)enc

代码示例:

代码语言:javascript
复制
NSString *originalUrl = @"https://www.xingshulin.com我是中文?p1=abc&p2=我是参数2";
NSString *encodeUrl = [originalUrl stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSLog(@"%@", encodeUrl);

编码结果:

代码语言:javascript
复制
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

代码语言:javascript
复制
- (nullable NSString *)stringByAddingPercentEncodingWithAllowedCharacters:(NSCharacterSet *)allowedCharacters

代码示例:

代码语言:javascript
复制
NSString *originalUrl = @"https://www.xingshulin.com我是中文?p1=abc&p2=我是参数2";
NSCharacterSet *encodeUrlSet = [NSCharacterSet URLQueryAllowedCharacterSet];
NSString *encodeUrl = [originalUrl stringByAddingPercentEncodingWithAllowedCharacters:encodeUrlSet];
NSLog(@"%@", encodeUrl);

编码结果:

代码语言:javascript
复制
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

代码语言:javascript
复制
URLFragmentAllowedCharacterSet  "#%<>[\]^`{|}

URLHostAllowedCharacterSet      "#%/<>?@\^`{|}

URLPasswordAllowedCharacterSet  "#%/:<>?@[\]^`{|}

URLPathAllowedCharacterSet      "#%;<>?[\]^`{|}

URLQueryAllowedCharacterSet    "#%<>[\]^`{|}

URLUserAllowedCharacterSet      "#%/:<>?@[\]^`

参考:http://blog.csdn.net/andanlan/article/details/53368727

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018.03.05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一、编码的原因和范围
    • 1. 为什么要编码
      • 2. 转码范围
      • 二、编码实现
        • 1. 使用CoreFoundation对url参数进行encode
          • 2. 使用Foundation框架对完整url进行encode
          • 三、拓展:stringByAddingPercentEncodingWithAllowedCharacters用法
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档