POST Request with AFNetworking 2.0 not working, but working in HTTP Request tester

十年热恋 提交于 2019-12-03 20:19:27

Now this returns a JSON of (NULL) and doesn't give me a status code like 404 or something (incidentally how do we attain the status code when using AFN 2.0?).

It should at least give an error. What does the failure handler print out?

So really my question is, why don't the parameters in the AFN 2.0 parameter property act in the same way as the parameters in the web app? And more generally why aren't the post request parameters working for me in AFN 2.0?

After examining how AFN (Version 2.0.1) encodes the parameters, it appears to me that these aren't encoded as they should: The application/x-www-form-urlencoded encoding algorithm.

Until this has been fixed, you may try the following workaround. The following algorithm encodes parameters strictly as suggested by w3c for HTTP 5, at least for Mac OS X 10.8 where I've tested it:

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:@"+"];
}

(Note: the code above depends on the implementation details of function CFURLCreateStringByAddingPercentEscapes. It's entirely possible to implement the suggested algorithm easily without any dependencies, which I would recommend - it becomes just not that short.)

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];
}

Then, when using AFN, you can customize the serializing algorithm as shown below:

    AFHTTPRequestOperationManager *operationManager = [AFHTTPRequestOperationManager manager];

    operationManager.requestSerializer.queryStringSerializationWithBlock = 
       ^NSString*(NSURLRequest *request,
                  NSDictionary *parameters,
                  NSError *__autoreleasing *error) {
        NSString* encodedParams = form_urlencode_HTTP5_Parameters(parameters);
        return encodedParams;
    };

Put / after the url. I've missed it for hours.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!