构建你的网络知识体系 - 为什么需要UrlEncode

·  阅读 90

网络封面.jpg

一、前言

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

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

二、哪些字符需要转义

在标准的url规范中,中文和很多别的字符是不允许出现在url中的。这些需要转义的字符,都将被替换成:%+ 2位16进制数

1、ASCII的控制字符

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

2、一些特殊字符

例如:emoji字符👴🏻👮🏽。特殊字符需要被转转义也是理所当然的。

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

url中的分隔符包含主要分隔符:#[]@?/和次要分隔符!$&'()*+,;=

url的query参数和值,如果在分隔符的包含范围内,除了?/外,都需要转义。例如:对于原始urlhttps://www.baidu.com?paramA=哈哈&paramB=&来说,哈哈paramB=&中的&就需要参与转义。哈哈是中文,所以需要转义。&在分隔符的包含范围内,所以也需要转义。如果不进行转义,后端收到后,会认为它是一个参数值,还是url本身的分隔符呢?

4、一些不安全的字符

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

三、AFNetworking的转义过程

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的原因。

分类:
iOS
标签:
收藏成功!
已添加到「」, 点击更改