【问题标题】:How to set HTTP request body using AFNetwork's AFHTTPRequestOperationManager?如何使用 AFNetwork 的 AFHTTPRequestOperationManager 设置 HTTP 请求正文?
【发布时间】:2013-10-31 17:05:06
【问题描述】:

我正在使用 AFHTTPRequestOperationManager(2.0 AFNetworking 库)进行 REST POST 请求。但经理只有设置参数的调用。

-((AFHTTPRequestOperation *)POST:(NSString *)URLString
                  parameters:(NSDictionary *)parameters
                     success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success
                     failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure;

我还需要使用字符串设置 HTTP 请求正文。我怎样才能使用 AFHTTPRequestOperationManager 来做到这一点?谢谢。

【问题讨论】:

    标签: ios iphone objective-c ipad afnetworking


    【解决方案1】:

    我遇到了同样的问题,通过添加代码解决了它,如下所示:

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL
                  cachePolicy:NSURLRequestReloadIgnoringCacheData  timeoutInterval:10];
    
    [request setHTTPMethod:@"POST"];
    [request setValue:@"Basic: someValue" forHTTPHeaderField:@"Authorization"];
    [request setValue: @"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody: [body dataUsingEncoding:NSUTF8StringEncoding]];
    
    AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    op.responseSerializer = [AFJSONResponseSerializer serializer];
    [op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
    
        NSLog(@"JSON responseObject: %@ ",responseObject);
    
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", [error localizedDescription]);
    
    }];
    [op start];
    

    【讨论】:

    • 但是AFHTTPRequestOperationManager怎么办?
    【解决方案2】:

    对于 AFHTTPRequestOperationManager

    [requestOperationManager.requestSerializer setValue:@"your Content Type" forHTTPHeaderField:@"Content-Type"];
    [requestOperationManager.requestSerializer setValue:@"no-cache" forHTTPHeaderField:@"Cache-Control"];
    
    // Fill parameters
    NSDictionary *parameters = @{@"name"        : @"John",
                                 @"lastName"    : @"McClane"};
    
    // Customizing serialization. Be careful, not work without parametersDictionary
    [requestOperationManager.requestSerializer setQueryStringSerializationWithBlock:^NSString *(NSURLRequest *request, NSDictionary *parameters, NSError *__autoreleasing *error) {
    
        NSData *jsonData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
        NSString *argString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
        return argString;
    }];
    
    [requestOperationManager POST:urlString parameters:parameters timeoutInterval:kRequestTimeoutInterval success:^(AFHTTPRequestOperation *operation, id responseObject) {
    
        if (success)
            success(responseObject);
    
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    
        if (failure)
            failure(error);
    }];
    

    【讨论】:

      【解决方案3】:

      检查该便捷方法 (POST:parameters:success:failure) 在后台执行的操作并自己执行以访问实际的 NSMutableRequest 对象。

      我使用的是 AFHTTPSessionManager 而不是 AFHTTPRequestOperation 但我想机制是相似的。

      这是我的解决方案:

      1. 设置会话管理器(标头等)

      2. 手动创建 NSMutable 请求并添加我的 HTTPBody,基本上是在该便捷方法中复制粘贴代码。看起来像这样:

        NSMutableURLRequest *request = [manager.requestSerializer requestWithMethod:@"POST" URLString:[[NSURL URLWithString:<url string>] absoluteString] parameters:parameters];
        
        [request setHTTPBody:[self.POSTHttpBody dataUsingEncoding:NSUTF8StringEncoding]];
        __block NSURLSessionDataTask *task = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
            if (error) {
               // error handling
            } else {
                // success
          }
        }];
        
        [task resume];
        

      【讨论】:

        【解决方案4】:

        如果您深入研究 AFNetworking 的来源,您会发现在 POST 的情况下,方法参数被设置到您的 HTTP 请求的正文中。

        每个键值字典对都以key1=value1&amp;key2=value2 的形式添加到正文中。对由 & 符号分隔。

        AFURLRequestSerialization.m 中搜索 application/x-www-form-urlencoded

        如果字符串只是一个字符串,而不是键值对,那么您可以尝试使用AFQueryStringSerializationBlock http://cocoadocs.org/docsets/AFNetworking/2.0.3/Classes/AFHTTPRequestSerializer.html#//api/name/setQueryStringSerializationWithBlock:但这只是我的猜测。

        【讨论】:

          【解决方案5】:

          您可以创建自己的 AFHTTPRequestSerializer 的自定义子类,并将其设置为您的 AFHTTPRequestOperationManager 的 requestSerializer。

          在这个自定义 requestSerializer 中,你可以重写

          - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request         
                                         withParameters:(id)parameters 
                                                  error:(NSError *__autoreleasing *)error;
          

          在此方法的实现中,您将可以访问 NSURLRequest,因此您可以执行类似的操作

          - (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request     
                                         withParameters:(id)parameters 
                                                  error:(NSError *__autoreleasing *)error  
          {    
              NSURLRequest *serializedRequest = [super requestBySerializingRequest:request withParameters:parameters
               error:error];
              NSMutableURLRequest *mutableRequest = [serializedRequest mutableCopy];          
              // Set the appropriate content type
              [mutableRequest setValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];              
              // 'someString' could eg be passed through and parsed out of the 'parameters' value
              NSData *httpBodyData = [someString dataUsingEncoding:NSUTF8StringEncoding];
              [mutableRequest setHTTPBody:httpBodyData];
          
              return mutableRequest;
          }
          

          您可以查看 AFJSONRequestSerializer 的实现,以获取设置自定义 HTTP 正文内容的示例。

          【讨论】:

            【解决方案6】:
            AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
            manager.requestSerializer = [AFJSONRequestSerializer serializer];
            [manager POST:url parameters:jsonObject success:^(AFHTTPRequestOperation *operation, id responseObject) {
                //success
            } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
                //fail
            }];
            

            这是我找到的最好和最简洁的方法。

            【讨论】:

            • 这比其他方法简单得多。然而奇怪的是,这似乎不适用于 GET ...
            • @Hampotato 通常,您的获取请求中不应包含正文。这是可能的,但不标准。
            • 是的,我想通了。谢谢tdeegan!
            • 这不是为了身体。
            【解决方案7】:

            也许我们可以使用 NSMutableURLRequest,这里是代码:

            NSURL *url = [NSURL URLWithString:yourURLString];
            NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                                   cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                               timeoutInterval:60.0];
            
            [request setHTTPMethod:@"POST"];
            NSData *JSONData = [NSJSONSerialization dataWithJSONObject:parameters options:NSJSONWritingPrettyPrinted error:nil];
            NSString *contentJSONString = [[NSString alloc] initWithData:JSONData encoding:NSUTF8StringEncoding];
            [request setHTTPBody:[contentJSONString dataUsingEncoding:NSUTF8StringEncoding]];
            
            NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
            [connection start];
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2013-02-18
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多