问题描述
我需要使用 NSURLSession 向服务器发送一个 post 请求。其中一个参数需要是一个 url 编码字符串。我在 Charles 中发现它不是我期望的格式。 这是代码。
DecimalFormat format = new DecimalFormat("#.####");
format.format(yourDoubleObject);
在 A 处,extraString 是 在 B 处,extraString 为 在 C 中,bodyString 是
NSMutableDictionary *md = [self defaultParams].mutablecopy;
[md setobject:@"track" forKey:@"$event_type"];
[md setobject:@"page" forKey:@"$event_name"];
NSDictionary *tempMd = @{@"message_id":@"776",@"msgid":@"MG-0703_111_857"};
Nsstring *extraString = nil;
if (tempMd.allKeys.count != 0) {
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:tempMd options:NSJSONWritingPrettyPrinted error:&error];
if (jsonData) {
extraString = [[Nsstring alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
//A
if (extraString.length != 0) {
extraString = [extraString stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
//B
[md setobject:extraString forKey:@"$extra"];
}
id params = md.copy;
NSError * error = nil;
Nsstring *paramsstring;
NSData *jsonData;
if ([params isKindOfClass:[NSDictionary class]]||[params isKindOfClass:[NSArray class]]) {
@try {
jsonData = [NSJSONSerialization dataWithJSONObject:params options:kNilOptions error:&error];
if (jsonData) {
paramsstring = [[Nsstring alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
}
}
@catch (NSException *exception) {
return;
}
@finally {
}
}
if (paramsstring.length > 0) {
Nsstring *bid = @"18.1.1";
NSDictionary *requestParams = @{@"data" : paramsstring,@"bid" : bid};
NSURL *url = [NSURL URLWithString:@"https://ec.log.mgtv.com/s.gif?"];
NSMutableuRLRequest *request = [[NSMutableuRLRequest alloc] initWithURL:url];
request.HTTPMethod = @"POST";
request.timeoutInterval = 20.;
Nsstring *bodyString = [self parseParams:requestParams];
//C
request.HTTPBody = [bodyString dataUsingEncoding:NSUTF8StringEncoding];
[[[NSURLSession sharedSession] dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data,NSURLResponse * _Nullable response,NSError * _Nullable error) {
NSLog(@"big data complete");
completeBlock();
}] resume];
}
+ (Nsstring *)parseParams:(NSDictionary *)params {
Nsstring *keyvalueFormat;
NSMutableString *result = [NSMutableString new];
NSMutableArray *array = [NSMutableArray new];
NSEnumerator *keyEnum = [params keyEnumerator];
id key;
while (key = [keyEnum nextObject]) {
keyvalueFormat = [Nsstring stringWithFormat:@"%@=%@&",key,[params valueForKey:key]];
[result appendString:keyvalueFormat];
[array addobject:keyvalueFormat];
}
return result;
}
但我的期望如下:
{"$os":"iOS","$is_vip":0,"biz_id":"MG-0703_111_859","$screen_width":390,"$app_version":"xm-iphone-1.0","$extra":"{
"messageid" : "859","msgid" : "MG-0703_111_859"
}","$event_name":"page","$model":"iPhone13_2","$network_type":"WIFI","$time":1625295930198,"device_id":"01f23f0160839dada3e3d214982df41bcf0220cc","$carrier":"中国电信","page_name":"push","$user_type":0,"$channel":"apple","$project":"mgtv-ec","$ua":"XMNotificationService\/1.0 (iPhone; iOS 14.6; Scale\/3.00)","biz_type":"push","$screen_height":844,"$is_login":0,"$event_type":"track","$lib_version":"1.0","$os_version":"14.6","$manufacturer":"Apple","$lib":"iOS","$is_ecom_vip":0}
我的问题是为什么 Charles 显示与 C 不同,我希望看到 {"$os":"iOS","$extra":"%7B%0A%20%20%22messageid%22%20:%20%22860%22,%0A%20%20%22msgid%22%20:%20%22MG-0703_111_860%22%0A%7D","$is_ecom_vip":0}
解决方法
在我看来,当显示 HTTP.Body 中的信息时,charles 代理正在解释 $extra 项目中的编码数据。当您准备好发送时,身体本身看起来很好。但它似乎已经采取了
%7B%0A%20%20%22me...
嵌入在正文中并将其解码为ascii。
问题实际上是它是在终点实际解码还是简单地在 Charles 演示模式下进行解码。当您查看服务器时,它是通过解码来的,还是作为 % 编码字符来的?
我建议以十六进制查看数据包并确保它不仅仅是您看到的演示信息......查尔斯文档表明这是可能的
“您始终可以看到 HTTP 请求和响应标头以及请求和响应正文,无论是纯文本还是二进制(十六进制和 ascii)。”
我会以十六进制进行检查,确保您看到的是真正的问题。