Obj-C 中的 HTTP 多部分请求

Posted

技术标签:

【中文标题】Obj-C 中的 HTTP 多部分请求【英文标题】:HTTP Multipart request in Obj-C 【发布时间】:2015-12-29 11:59:08 【问题描述】:

序幕

所以我正在制作 android 应用程序的 ios 版本。所有的 web 服务都已经设置好了,但是它们没有太多详细的文档,所以我选择从 android 代码中推断出来。该项目已完成,除了一件小事 - 一个 HTTP 多部分请求

我需要什么

我需要实现一个从javaobjective-c网络请求。它的作用是将 图像 连同 用户 ID 上传到服务器并获得响应。这是相关的Java代码:

HttpClient httpClient = new DefaultHttpClient();
HttpPost postRequest=new HttpPost(Constant.server_url+"usermain/Profileimagesave");
String fileName = String.format("File_%d.png",new Date().getTime());
ByteArrayBody bab = new ByteArrayBody(data, fileName);
            
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
reqEntity.addPart("file", bab);
reqEntity.addPart("WebID", new StringBody(SharedPreferenceSession.getValue(getApplicationContext(), "WebId")));
postRequest.setEntity(reqEntity);

我尝试了什么

我已经尝试了将近一周的时间来将这段代码模仿成objective-c。这是我在接受stefan's answer 后可以管理的:

[manager POST:urlstr parameters:nil
constructingBodyWithBlock:^(id<AFMultipartFormData> formData)
  [formData appendPartWithFileData:imageData
                              name:@"blahblah.jpg"
                          fileName:@"blahblah.jpg"
                          mimeType:@"image/jpeg"];

  [formData appendPartWithFormData:[webid dataUsingEncoding:NSUTF8StringEncoding]
                              name:@"WebID"];

     progress:nil
      success:^(NSURLSessionTask *task, id responseObject) 
          NSLog(@"Response: %@", responseObject);
      
      failure:^(NSURLSessionTask *operation, NSError *error) 
          NSLog(@"%@",[error.userInfo objectForKey:JSONResponseSerializerWithDataKey]);
];

我一直在尝试上面代码的很多变体,但是由于我对多部分请求没有清楚的理解,所以我觉得我在绕圈子。

我得到了什么

我从服务器收到 500 错误。

php 警告

copy(../UserData/ThumbPhotos/MOB274565CCM_20151230062220.):无法打开流:没有这样的文件或目录

1773 $login1=$login->登录ID; 第1774章 第1775章 $currentname=$webid."_".+$curr_date; 1776 第1777章//回显“文件大小:”。 第1778章 第1779章 1780 $filename="$currentname.$ext"; 第1781章 1782 $targetPath="../UserData/ThumbPhotos/".$filename; 1783 $targetPath1="../UserData/UserPhoto/".$filename; 第1784章 移动上传文件($sourcePath,$targetPath);

1785 复制($targetPath,$targetPath1);

1786 $userfiles=新用户文件; 第1787章 第1788章 第1789章 第1790章 第1791章 第1792章 第1793章 第1794章 第1795章 第1796章 第1797章

有什么帮助

我无法理解上述代码中发生的事情,因为我不熟悉 HTTP 请求的功能。因此,欢迎任何可以帮助我理解这一点的内容,可能是工作代码示例调试请求的提示或关于这些事情如何工作的 cmets强>。

android 代码运行良好。那么有什么方法可以检查 android 和 iOS 应用程序上的传出请求,并尝试通过反复试验来匹配它们?

提前致谢

【问题讨论】:

您有兴趣使用 AFNetworking 吗?这可以节省一些代码和时间... @Stefan 是的。但我不确定如何将 java 代码移植到 obj-c 【参考方案1】:

我建议您使用AFNetworking。 在这种情况下,你想上传一些图片,所以我会给你代码:

NSData *imageData = [NSData dataWithContentsOfFile:filename];
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];

[manager POST:urlString parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) 
    [formData appendPartWithFileData:imageData
                                name:@"files"
                            fileName:photoName mimeType:@"image/jpeg"];
[formData appendPartWithFormData:[key1 dataUsingEncoding:NSUTF8StringEncoding]
                            name:@"key1"];

 success:^(AFHTTPRequestOperation *operation, id responseObject) 
    NSLog(@"Response: %@", responseObject);
 failure:^(AFHTTPRequestOperation *operation, NSError *error) 
    NSLog(@"Error: %@", error);
];

【讨论】:

没问题。此代码将在服务器上上传一张图片...您可以附加更多图片...如果您有一些需要发送的参数,只需使用字典...如果您想了解更多信息,请告诉我,所以我可以编辑我的答案... 好像是3.0,我用的是2.0...请阅读github.com/AFNetworking/AFNetworking/wiki/…并查看3.0的代码...这是新的更新。我觉得你只需要把AFHTTPRequestOperationManager改成AFHTTPSessionManager *manager = [AFHTTPSessionManager manager]; 将“text/html”添加到 AFURLResponseSerialization 类中设置的可接受内容类型。只需搜索“acceptableContentTypes”并手动将@“text/html”添加到集合中。 感谢您的支持。我切换到 AFNetworking(更新问题)。完全值得学习曲线。所以现在我可以正确调试错误了。但它仍然会引发错误。有什么想法吗? 如果您收到 500 服务器代码错误,那是在服务器端...pcsupport.about.com/od/findbyerrormessage/a/500servererror.htm【参考方案2】:

尝试使用 NSMutableURLRequest 上传任何图片

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:YOUR_URL]];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"---------------------------14737809831466499882746641449";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request addValue:contentType forHTTPHeaderField:@"Content-Type"];

NSMutableData *body = [NSMutableData data];

[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"uploadfile\"; filename=\"%@.jpg\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:_YOUR_IMAGE_DATA]];

[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"posttype\"\r\n\r\n%@", postType] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"postimgtext\"\r\n\r\n%@", postTextType] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"userid\"\r\n\r\n%@", USER_ID] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];

NSError *error = nil;
NSURLResponse *response = nil;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
if (!error) 
     NSString *response = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
     NSLog(@"response : %@", response);

【讨论】:

以上是关于Obj-C 中的 HTTP 多部分请求的主要内容,如果未能解决你的问题,请参考以下文章

请求音乐库权限 swift 或 obj-c

HTTP中的请求与响应

在 Python 3 中为 HTTP 请求创建带有二进制组件的多部分 MIME 消息

在多部分 http 请求中指定驻留在文件上的 bigquery 表架构

如何使用 Apache HttpComponentst 创建和发布多部分/混合 http 请求?

obj-c AFNetworking 2.0 POST 请求不起作用