美文网首页
ios字典转json字符串带来格式符的坑

ios字典转json字符串带来格式符的坑

作者: ios周周 | 来源:发表于2020-03-11 17:55 被阅读0次

    背景交代:
    因为请求需要签名,签名要拼上请求参数的json字符串。发现一个问题,ios把参数转成json后会有一些类似空格和\n这样的格式符。导致算出来的签名是带上这些格式符的。服务端从请求体拿到的是个字典对象key=value,是没有这些格式符的。所有会签名校验失败。

    因为这是ios字典转json产生的格式符,只能ios自己处理。
    以下为过滤格式符的代码,暂时解决了有格式符产生算出签名不一致的问题。

        NSString *messageJSON = @"";
        if (![NSJSONSerialization isValidJSONObject:encodePram]) {
            NSLog(@"不是有效的json类型");
            return @"";
        }else
        {
            messageJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:encodePram options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding];
            
        }
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r\n" withString:@"" ];
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString : @"" ];
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\t" withString : @"" ];
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@" " withString : @"" ];
    
    

    但是又引入一个问题,就是如果key或者value有空格和\n这类的格式符,那么真正有意义的内容就会被无意修改到,也会导致签名不对。

    后来我想到的解决办法是,在转json前先把key和value进行urlencode,这时候出来的字符串就是带了json格式多余的那些空格和\n的,而内容key和value已经被urlencode,这时候过滤json格式符不会把真正的内容过滤掉。

    过滤完之后,再对整个字符串来个urlDecode,问题解决。

    + (NSString *)yxNetWorkJsonString:(id)pram{
        if (!([pram isKindOfClass:[NSDictionary class]]||[pram isKindOfClass:[NSArray class]])) {
            return @"{}";
        }
        
        if (!pram) {
            return @"{}";
        }
        
        //pram对key和value进行urlencode
        id encodePram = [self urlEncodeKeyAndValue:pram];
        
        NSString *messageJSON = @"";
        if (![NSJSONSerialization isValidJSONObject:encodePram]) {
            NSLog(@"不是有效的json类型");
            return @"";
        }else
        {
            messageJSON = [[NSString alloc] initWithData:[NSJSONSerialization dataWithJSONObject:encodePram options:NSJSONWritingPrettyPrinted error:NULL] encoding:NSUTF8StringEncoding];
            
        }
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\r\n" withString:@"" ];
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\n" withString : @"" ];
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@"\t" withString : @"" ];
        messageJSON = [messageJSON stringByReplacingOccurrencesOfString:@" " withString : @"" ];
        
        //对整个字符串url decode
        messageJSON = [messageJSON jk_urlDecode];
        return messageJSON;
    }
    

    递归encode

    + (id)urlEncodeKeyAndValue:(id)target
    {
        if (!([target isKindOfClass:[NSDictionary class]]||[target isKindOfClass:[NSArray class]])) {
            return nil;
        }
        if ([target isKindOfClass:[NSDictionary class]]) {
            NSMutableDictionary *result = [NSMutableDictionary new];
            [target enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
                id NewKey = key;
                id NewValue = obj;
                if ([key isKindOfClass:[NSString class]]) {
                    NewKey = [key jk_urlEncode];
                }
                if ([obj isKindOfClass:[NSString class]]) {
                    NewValue = [obj jk_urlEncode];
                }else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSArray class]])
                {
                    NewValue = [self urlEncodeKeyAndValue:obj];
                }
                [result setObject:NewValue forKey:NewKey];
            }];
            return result;
        }else
        {
            //array
            NSMutableArray * result = [NSMutableArray new];
            
            [target enumerateObjectsUsingBlock:^(id  _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
                id NewValue = obj;
    
                if ([obj isKindOfClass:[NSString class]]) {
                    NewValue = [obj jk_urlEncode];
                }else if ([obj isKindOfClass:[NSDictionary class]] || [obj isKindOfClass:[NSArray class]])
                {
                    NewValue = [self urlEncodeKeyAndValue:obj];
                }
                [result addObject:NewValue];
            }];
            
            
            return result;
        }
    }
    
    

    相关文章

      网友评论

          本文标题:ios字典转json字符串带来格式符的坑

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