为什么需要urlEncode

urlEncode,主要是为了让url的参数可以被准确无误的传输

字符串数据以url的形式传递给web服务器时,对字符是有限制的。为了符合url的规范,这些被限制的字符,就需要被转义。比方说:把一个邮箱放入url就需要转义,因为邮箱中包含限制字符@

在标准的url规范中,中文和很多的字符是不允许出现在url中的。这些需要转义的字符都将被替换成%后跟两位十六进制数。

哪些字符需要转义

1、ASCII的控制字符

这些字符都是不可打印的,自然需要进行转化。

2、一些特殊字符

例如:emoji字符,转化也是理所当然的。

3、与url分隔字符相同的字符

url中的分隔符包含主要分隔符:#[]@?/和次要分隔符!$&'()*+,;=。对于url的query参数和值,如果在分隔符的包含范围内,除了?/外,都需要转义。例如:对于原始urlhttps://www.baidu.com?paramA=哈哈¶mB=&来说,哈哈paramB=&中的&就需要参与转义。否则,对于&来说,你认为它是一个参数值,还是url本身的分隔符呢?

4、一些不安全的字符

例如:空格。为了避免歧义,需要被转化成+或者%20。具体转换成+还是%20主要依据不同的转换标准。

AFURLRequestSerialization的转义过程

AFURLRequestSerialization的源码很好地说明了转义的过程和规则:

//对string进行url转义
NSString * AFPercentEscapedStringFromString(NSString *string) {
    
    //需要参与参与转义的分隔符
    static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
    static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";//子分隔符

    //从query参数可用的字符集中把:#[]@和!$&'()*+,;=去除,得到不用参与转义的字符集
    NSMutableCharacterSet *allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
    [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];

    static NSUInteger const batchSize = 50;//每次转码的最大长度,修复对超长中文字符串转义会导致闪退的问题

    NSUInteger index = 0;
    NSMutableString *escaped = @"".mutableCopy;

    while (index < string.length) {
        NSUInteger length = MIN(string.length - index, batchSize);
        NSRange range = NSMakeRange(index, length);

        // 等emoji的长度不是一,为了避免原来的range切断emoji,对原来range扩展一下
        range = [string rangeOfComposedCharacterSequencesForRange:range];

        NSString *substring = [string substringWithRange:range];
        NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];//除了不用参与转义的字符,其他字符都应该参与转义
        [escaped appendString:encoded];

        index += range.length;
    }

    return escaped;
}

你可能感兴趣的:(为什么需要urlEncode)