iOS URL编码和URL拼接(如含中文等特殊符号).md

  • URL编码默认使用的字符集是US-ASCII.对于非ASCII字符, 需要使用ASCII字符集的超级进行编码.
  • URL中只允许包含4种字符:
英文字符 : a-zA-Z
数字: 0-9
-_.~ 4个特殊字符.
保留字符: ! * ' ( ) ; : @ & = + $ , / ? # [ ]

URL编码使用%其后跟随两位(中文是三位)的十六进制数来替换非ASCII字符,
不能在URL中包含任何非ASCII字符, 如中文字符等.

基本的NSURL

NSString *urlString = @"https://www.baidu.com";
NSURL *url = [NSURL URLWithString:urlString];

但是, 若urlString中含有中文等非URL允许的字符时, 创建的NSURL对象为nil.

iOS 7之后: stringByAddingPercentEncodingWithAllowedCharacters

NSString *latestUrl = @"https://www.baidu.com?name=小明&age=20";

latestUrl = [[latestUrl copy] stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

///https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20



/**

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

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

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

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

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

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

 */

///自定义的字符集

NSString *latestUrl_2 = @"https://www.baidu.com?name=小明&age=20";

NSCharacterSet *defaultCharacterSet = [NSCharacterSet characterSetWithCharactersInString:@"?&=/ "];

if (defaultCharacterSet) {

    NSString *latestUrl_2_defaultAllow = [[latestUrl_2 copy] stringByAddingPercentEncodingWithAllowedCharacters:defaultCharacterSet];

    /**

     %68%74%74%70%73%3A//%77%77%77%2E%62%61%69%64%75%2E%63%6F%6D?%6E%61%6D%65=%E5%B0%8F%E6%98%8E&%61%67%65=%32%30

     可以看出除了?&=/ ,其他字符都被编码了.

     */



    //invertSet

    NSCharacterSet *invertCharacterSet = defaultCharacterSet.invertedSet;

    latestUrl_2 = [[latestUrl_2 copy] stringByAddingPercentEncodingWithAllowedCharacters:invertCharacterSet];

    /**

     https:%2F%2Fwww.baidu.com%3Fname%3D%E5%B0%8F%E6%98%8E%26age%3D20

     */

}

/// 服务端会对请求进行UTF-8解码一次,请确保请求中的字符只进行一次UTF-8编码。


URL中含有中文并且拼接额外参数

NSString *originUrlString = @"https://www.baidu.com?name=小明&age=20";





//需要拼接的参数:转为通过&拼接

NSMutableDictionary *urlParamsDic = [NSMutableDictionary dictionary];

[urlParamsDic setValue:@"22" forKey:@"sex"];

[urlParamsDic setValue:@"one" forKey:@"class"];

__block NSMutableString *joinStr = [NSMutableString string];

if (urlParamsDic && [urlParamsDic isKindOfClass:[NSDictionary class]] && urlParamsDic.count) {

    

    [urlParamsDic enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {

        if (key && obj) {

            [joinStr appendFormat:@"%@=%@&",key,obj];

        }

    }];

    if ([joinStr hasSuffix:@"&"]) {

        [joinStr deleteCharactersInRange:NSMakeRange(joinStr.length-1, 1)];

    }

}

///joinStr = sex=22&class=one



/**

 *url中含有中文,先对其encode生成NSURL

 * 拼接后再decode,最后再对拼接后的encode

 */

//1.encode生成NSURL

NSURL *originUrl = [NSURL URLWithString:[originUrlString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]]];

///originUrl = https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20

//2.在url后拼接参数

NSString *latestURLString = @"";

BOOL cointainQuery = NO;

if (joinStr.length == 0 || [originUrl.query rangeOfString:joinStr].location != NSNotFound) {

    //其中,若joinStr = 0则表示默认包含该空字符串

    cointainQuery = YES;///

}



if (cointainQuery) {

    latestURLString = originUrl.absoluteString;

}else{

    ///originUrl.query: name=%E5%B0%8F%E6%98%8E&age=20

    if (originUrl.query.length>0) {

        latestURLString = [NSString stringWithFormat:@"%@&%@", originUrl.absoluteString,joinStr];

        ///https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20&sex=22&class=one

    }else{

        BOOL hasSuffix = [originUrl.absoluteString hasSuffix:@"?"];

        latestURLString = [NSString stringWithFormat:@"%@%@%@",originUrl.absoluteString, hasSuffix ? @"":@"?", joinStr];

    }

}

///

//3.拼接后decode

latestURLString = [latestURLString stringByRemovingPercentEncoding];

///latestURLString = https://www.baidu.com?name=小明&age=20&sex=22&class=one

///

//4.最后对对接后的encode

latestURLString =  [latestURLString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];

///latestURLString =https://www.baidu.com?name=%E5%B0%8F%E6%98%8E&age=20&sex=22&class=one

NSLog(@"%@",latestURLString);


你可能感兴趣的:(iOS URL编码和URL拼接(如含中文等特殊符号).md)