将加密字符串转为NSData作为HTTP Body时出现400错误排查
我在Objective-C中对JSON字符串进行加密,将其转换为NSData后作为HTTP请求的Body发送,按标准流程操作却返回400 Bad Request错误,但该请求在Postman中可正常运行。推测问题出在iOS端,希望有人帮忙指出可能的问题所在。
参考代码
NSData *datas = [NSJSONSerialization dataWithJSONObject:paramsDic options:NSJSONWritingPrettyPrinted error:nil]; NSString *jsonStrings = [[NSString alloc] initWithData:datas encoding:NSUTF8StringEncoding]; NSString *jencWithPubKey = [EncryptionAlgorithm encryptString:jsonStrings publicKey:APP_PUBLIC_KEY2]; NSData *data1 = [jencWithPubKey dataUsingEncoding:NSUTF8StringEncoding]; NSLog(@"Value of json string %@", jencWithPubKey); NSMutableURLRequest *urlRequest = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:QMMemberLogin]]; NSDictionary *heads =@{@"User-Agent":@"Apifox/1.0.0(https://apifox.com)", @"Content-Type":@"appliction/json; charset=UTF-8", @"Accept":@"*/*", @"Conection":@"keep-alive"}; [urlRequest setAllHTTPHeaderFields:heads]; //Apply the data to the body [urlRequest setHTTPBody:data1]; //create the Method "GET" or "POST" [urlRequest setHTTPMethod:@"POST"]; NSURLSession *session = [NSURLSession sharedSession]; NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; if(httpResponse.statusCode == 200) { NSError *parseError = nil; NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError]; NSLog(@"The response is - %@",responseDictionary); NSInteger success = [[responseDictionary objectForKey:@"success"] integerValue]; if(success == 1) { NSLog(@"Login SUCCESS"); } else { NSLog(@"Login FAILURE"); } } else { NSLog(@"Error"); } }]; [dataTask resume];
可能的问题点
请求头拼写错误:
Content-Type字段拼写错误,写成了appliction/json,正确应为application/jsonConnection字段拼写错误,写成了Conection,正确应为Connection
这两个拼写错误会导致服务器无法正确识别请求格式,直接返回400错误。
JSON序列化格式不一致:
使用NSJSONWritingPrettyPrinted选项生成的是带换行、缩进的格式化JSON字符串,加密后的数据会和Postman中使用的紧凑JSON加密结果存在差异。建议改为使用0(默认无格式)或者NSJSONWritingWithoutEscapingSlashes,确保生成的JSON是紧凑结构,和Postman的请求体原始JSON一致。加密数据转NSData方式错误:
非对称加密后的结果通常会用Base64编码为可打印字符串,直接用dataUsingEncoding:NSUTF8StringEncoding转换可能导致数据损坏。如果encryptString:publicKey:返回的是Base64字符串,应该用Base64解码方式转成NSData:NSData *data1 = [[NSData alloc] initWithBase64EncodedString:jencWithPubKey options:NSDataBase64DecodingIgnoreUnknownCharacters];缺失关键错误处理:
代码中忽略了NSJSONSerialization的序列化错误,若paramsDic无法正常序列化为JSON,后续加密的就是无效字符串。建议添加错误判断:NSError *jsonError = nil; NSData *datas = [NSJSONSerialization dataWithJSONObject:paramsDic options:0 error:&jsonError]; if (jsonError) { NSLog(@"JSON序列化失败:%@", jsonError); return; }同时建议给
EncryptionAlgorithm的加密方法添加错误返回逻辑,确认加密操作是否成功,避免发送无效加密数据。请求方法设置顺序问题:
代码中先设置HTTPBody再设置HTTPMethod,虽然不影响功能,但建议调整顺序为先设置POST方法,再设置请求Body,保持逻辑一致性。
内容的提问来源于stack exchange,提问作者Ankit Tayde

