美文网首页
iOS原生请求 post 参数包含 & 失败的解决方案

iOS原生请求 post 参数包含 & 失败的解决方案

作者: 小明2021 | 来源:发表于2023-03-22 19:02 被阅读0次

    最近自己用NSMutableURLRequest 写post请求的时候,遇到的问题:

    post的某一个参数里面包含 & 由于默认的url编码不会把 & 转义,所以导致请求的时候,把 & 当成了拼接参数的符号了,导致把参数拆分并请求失败

    失败的原因是:

    请求的时候url是用 & 符号拼接的,所以url的编码是不会把 & 转义的,但是参数里面如果包含 & 就需要想办法转义了。 平时之所以没遇到这个问题,是因为AFNetworking已经帮我们做了这部分工作。

    解决方案:

    确保 参数字典转成json的时候,保证每一个参数里面都不包含 & ,可以手动把 & 转义成 %26 ,也可以用网上的方案统一编码。 请求的时候,把 json 正常转成 data 就OK了。

    AFNetworking 处理类似问题的解决方案是:

    思路是不用系统的字典转json,而是自己用for循环把每一个字典的字段都用 & 收到拼接下,并且把每个字段值的特殊字符都转义了。

    /**
     Returns a percent-escaped string following RFC 3986 for a query string key or value.
     RFC 3986 states that the following characters are "reserved" characters.
        - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
        - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
    
     In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
     query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
     should be percent-escaped in the query string.
        - parameter string: The string to be percent-escaped.
        - returns: The percent-escaped string.
     */
    NSString * AFPercentEscapedStringFromString(NSString *string) {
        static NSString * const kAFCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4
        static NSString * const kAFCharactersSubDelimitersToEncode = @"!$&'()*+,;=";
    
        NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy];
        [allowedCharacterSet removeCharactersInString:[kAFCharactersGeneralDelimitersToEncode stringByAppendingString:kAFCharactersSubDelimitersToEncode]];
    
        // FIXME: https://github.com/AFNetworking/AFNetworking/pull/3028
        // return [string stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
    
        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);
    
            // To avoid breaking up character sequences such as 👴🏻👮🏽
            range = [string rangeOfComposedCharacterSequencesForRange:range];
    
            NSString *substring = [string substringWithRange:range];
            NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet];
            [escaped appendString:encoded];
    
            index += range.length;
        }
    
        return escaped;
    }
    

    相关文章

      网友评论

          本文标题:iOS原生请求 post 参数包含 & 失败的解决方案

          本文链接:https://www.haomeiwen.com/subject/rmrbrdtx.html