iOS- AFNETWORKING 2.0 -AFHTTPRequestOperationManager - POST-MULTIPART-REQUEST

Posted

技术标签:

【中文标题】iOS- AFNETWORKING 2.0 -AFHTTPRequestOperationManager - POST-MULTIPART-REQUEST【英文标题】: 【发布时间】:2013-11-04 11:22:34 【问题描述】:

我已经构建了一个 API 客户端来与我的网络服务器进行通信,并且我的应用程序中的所有 HTTP 请求都是使用这个类完成的:(AFHTTPRequestOperationManager 的子类)

    + (SNPAPIClient *)sharedClient 
          static SNPAPIClient *_sharedClient = nil;
          static dispatch_once_t onceToken;
           dispatch_once(&onceToken, ^
               NSURL *baseURL = [NSURL URLWithString:BASE_URL];

                _sharedClient = [[SNPAPIClient alloc] initWithBaseURL:baseURL];
                _sharedClient.responseSerializer = [AFJSONResponseSerializer serializer];
                _sharedClient.requestSerializer = [AFJSONRequestSerializer serializer];

            );


      return _sharedClient;
 

该类有 3 种 POST、GET 和 POST-MULTIPART 方法。虽然 POST 和 GET 方法可以完美运行,但我在使用 POST-MULTIPART 时遇到了问题。

    -(void)httpPOSTMultiPartRequestWithPath:(NSString*)path Parameters:(NSDictionary*)parameters BodyBlock:(id)bodyBlock Completion:(APICompletionBlock)apiComp
comp = apiComp;
                            [self POST:path
                            parameters:parameters
             constructingBodyWithBlock:bodyBlock
                               success:^(NSURLSessionDataTask *task, id responseObject) 
                                    comp(responseObject,nil);
                                    
                               failure:^(NSURLSessionDataTask *task, NSError *error) 
                                    comp(nil,error);
                                ];
  

具体来说,我正在尝试向服务器发送一个简单的 JSON,然后是一个图像。我试过做这样的事情:

我正在调用我的控制器:

NSDictionary *POSTpic = [NSDictionary dictionaryWithObjectsAndKeys:@"109",@"userId",@"P",@"contentType", nil];    

NSURL *pictuePath = [NSURL fileURLWithPath:@"cat.JPG"];

[[SNPAPIClient sharedClient]httpPOSTMultiPartRequestWithPath:@"PATH_GOES_HERE"
                                                  Parameters:POSTpic
                                                   BodyBlock:^(id<AFMultipartFormData> formData) 
                                                       [formData appendPartWithFileURL:pictuePath name:@"profile" error:nil];
                                                   
                                                  Completion:^(id serverResponse, NSError *error)
                                                      if (serverResponse)
                                                          NSLog(@"success");
                                                      else
                                                          NSLog(@"error: %@",error);
                                                      
                                                  ];

发送此请求我在调试器中收到以下错误:

    internal server error (500)" UserInfo=0xb681650 NSErrorFailingURLKey=http://"my_path",      AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xb347d40>  URL: http://"my_path"             status code: 500, headers 
         "Content-Length" = 142;
         "Content-Type" = "text/plain";
          Date = "Wed, 06 Nov 2013 19:26:05 GMT";
         "Proxy-Connection" = "Keep-alive";
          Server = "nginx admin";
       , NSLocalizedDescription=Request failed: internal server error (500)

出于某种原因,即使我发送了一个 NSDictionary 并且我的请求序列化器设置为 AFJSONRequestSerializer,也不会创建 JSON 对象。 同样,这只发生在 POST MULTIPART 中,使用相同客户端和设置完成的其他请求会得到正确处理。

谢谢!

【问题讨论】:

【参考方案1】:

服务器正在发回带有status code 500 的响应,这意味着您的服务器在尝试处理请求时遇到了错误。您使用 AFNetworking 的方式似乎没有任何问题,但唯一的判断方法是首先在服务器端进行调试。

【讨论】:

【参考方案2】:

我解决这个问题已经有一段时间了,但也许这仍然可以帮助某人。最终,在我的例子中,上层 httpPOSTMultiPartRequestWithPath 方法没有被删除,我需要在消息结构中具有更大的灵活性(例如,设置自定义边界)。我最终使用了 HTTPRequestOperationWithRequest 方法并手动创建了 URLrequest。

-(void)httpPOSTmultipartContentWithPath:(NSString*)path Parameters:(NSDictionary*)parameters Body:(NSData*)body Completion:(APICompletionBlock)apiComp

    NSURL *pathURL = [NSURL URLWithString:path];
    NSURLRequest *request = [self POSTRequestWithURL:pathURL DataDictionary:parameters andBody:body];

    AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request
                                                                      success:^(AFHTTPRequestOperation *operation, id responseObject) 
                                                                          apiComp(responseObject,nil);
                                                                       failure:^(AFHTTPRequestOperation *operation, NSError *error) 
                                                                          apiComp(nil,error);
                                                                      ];

    [operation start];


- (NSMutableURLRequest *)POSTRequestWithURL:(NSURL *)url DataDictionary:(NSDictionary *)dictionary andBody:(NSData*)body


    // Create a POST request
    NSMutableURLRequest *myMedRequest = [NSMutableURLRequest requestWithURL:url];
    [myMedRequest setHTTPMethod:@"POST"];

    // Add HTTP header info

    NSString *boundary = @"*****";
    NSString *lineEnd = @"\r\n";
    NSString *twoHyphens = @"--";
    [myMedRequest addValue:[NSString stringWithFormat:@"multipart/form-data;boundary= %@", boundary] forHTTPHeaderField:@"Content-Type"];

    //create HTTP Body
    NSMutableData *POSTBody = [NSMutableData data];
    [POSTBody appendData:[[NSString stringWithFormat:@"boundary=%@%@%@",twoHyphens,boundary,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"Content-Type:multipart/related;type=application/json;boundary=%@%@%@%@",twoHyphens,twoHyphens,boundary,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"Content-Id:jsonTemp%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"json\"%@%@", lineEnd,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    //add JSON dictionary with request inforamtion
    [POSTBody appendData:[[NSString stringWithFormat:@"%@%@",dictionary
     ,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];

    [POSTBody appendData:[lineEnd dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"%@%@%@",twoHyphens,boundary,lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"Content-Type:image/jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"Content-Id:%@",@"profile.jpg"] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];

    // Add image data
    [POSTBody appendData:body];


    // Add the closing -- to the POST Form
    [POSTBody appendData:[[NSString stringWithFormat:@"%@",lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];
    [POSTBody appendData:[[NSString stringWithFormat:@"%@%@%@%@",twoHyphens,boundary,twoHyphens, lineEnd] dataUsingEncoding:NSUTF8StringEncoding]];


    // Add the body to the myMedRequest & return
    [myMedRequest setHTTPBody:POSTBody];
    return myMedRequest;

【讨论】:

【参考方案3】:

我在 Rails 3.1 上遇到了类似的问题,升级到 3.2 为我解决了这个问题。

【讨论】:

以上是关于iOS- AFNETWORKING 2.0 -AFHTTPRequestOperationManager - POST-MULTIPART-REQUEST的主要内容,如果未能解决你的问题,请参考以下文章

AFNetworking 2.0 iOS 7 复制与 AFHTTPRequestOperation.h 文件中的区域警告

AFNetworking 2.0 + TLS 1.2

iOS- AFNETWORKING 2.0 -AFHTTPRequestOperationManager - POST-MULTIPART-REQUEST

连接 JSON AFnetworking 2.0

iOS Afnetworking 2.0 AfSecurityPolicy.m 在构建项目时显示错误

AfNetworking 2.0 发布问题