我刚刚开始使用新的AFNetworking 2.0
API,暂时使用了以前的版本。我正在尝试做一个沼泽标准http POST request
,但遗憾的是我做得不太好。这是我目前的代码:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"username" : self.usernameField.text,
@"password" : self.passwordField.text};
[operationManager POST:@"https:URL GOES HERE" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", [responseObject description]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
现在这会返回JSON
(NULL)
并且不会给我一个状态代码,例如404
或其他东西(顺便说一句,我们如何在使用AFN 2.0时获得状态代码?) 。但是,当我尝试使用apikitchen.com这样的网络应用程序来测试HTTP Post request
对我来说,当我将用户名和密码放在param
字段中时,它会起作用。所以我的问题是,为什么parameters
中AFN 2.0 parameter property
的行为与网络应用中parameters
的行为方式不同?更一般地说,为什么post request parameters
中的AFN 2.0
不适合我?
提前感谢您的帮助,
麦克
编辑:我正在努力实施建议的修复程序。我的Post方法现在看起来像这样,但现在对我来说没有意义。
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
NSDictionary *parameters = @{@"username" : self.usernameField.text,
@"password" : self.passwordField.text};
operationManager.requestSerializer.queryStringSerializationWithBlock =
^NSString*(NSURLRequest *request,
NSDictionary *parameters,
NSError *__autoreleasing *error) {
NSString* encodedParams = form_urlencode_HTTP5_Parameters(parameters);
return encodedParams;
};
[operationManager POST:@"URL HERE" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"JSON: %@", [responseObject description]);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Error: %@", error);
}];
答案 0 :(得分:2)
现在这会返回一个(NULL)的JSON并且不会给我一个像404或者其他东西的状态代码(顺便说一句,我们如何在使用AFN 2.0时获得状态代码?)。
至少应该给出错误。故障处理程序打印出来的是什么?
所以我的问题是,为什么AFN 2.0参数属性中的参数与Web应用程序中的参数的作用方式不同?更一般地说为什么AFN 2.0中的post请求参数不适合我?
在检查AFN(版本2.0.1)如何对参数进行编码之后,在我看来,这些参数不是按照它们应该编码的:The application/x-www-form-urlencoded encoding algorithm。
在修复此问题之前,您可以尝试以下解决方法。以下算法严格按照W3c对HTTP 5的建议对参数进行编码,至少对于Mac OS X 10.8,我已对其进行了测试:
static NSString* form_urlencode_HTTP5_String(NSString* s) {
CFStringRef charactersToLeaveUnescaped = CFSTR(" ");
CFStringRef legalURLCharactersToBeEscaped = CFSTR("!$&'()+,/:;=?@~");
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(
kCFAllocatorDefault,
(__bridge CFStringRef)s,
charactersToLeaveUnescaped,
legalURLCharactersToBeEscaped,
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}
(注意:上面的代码取决于函数CFURLCreateStringByAddingPercentEscapes
的实现细节。完全有可能轻松实现建议的算法而没有任何依赖性,我建议 - 它变得不那么短。)
static NSString* form_urlencode_HTTP5_Parameters(NSDictionary* parameters)
{
NSMutableString* result = [[NSMutableString alloc] init];
BOOL isFirst = YES;
for (NSString* name in parameters) {
if (!isFirst) {
[result appendString:@"&"];
}
isFirst = NO;
assert([name isKindOfClass:[NSString class]]);
NSString* value = parameters[name];
assert([value isKindOfClass:[NSString class]]);
NSString* encodedName = form_urlencode_HTTP5_String(name);
NSString* encodedValue = form_urlencode_HTTP5_String(value);
[result appendString:encodedName];
[result appendString:@"="];
[result appendString:encodedValue];
}
return [result copy];
}
然后,使用AFN时,您可以自定义序列化算法,如下所示:
AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];
operationManager.requestSerializer.queryStringSerializationWithBlock =
^NSString*(NSURLRequest *request,
NSDictionary *parameters,
NSError *__autoreleasing *error) {
NSString* encodedParams = form_urlencode_HTTP5_Parameters(parameters);
return encodedParams;
};
答案 1 :(得分:0)
将/
放在网址后面。我已经错过了几个小时了。