AFNetworking 2.0的POST请求不起作用,但在HTTP请求测试程序中工作

时间:2013-10-14 15:46:39

标签: iphone ios objective-c afnetworking afnetworking-2

我刚刚开始使用新的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字段中时,它会起作用。所以我的问题是,为什么parametersAFN 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);
}];

2 个答案:

答案 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)

/放在网址后面。我已经错过了几个小时了。