ios - 使用一个 NSURL 请求发布图像和 JSON 数据

标签 ios django json curl django-rest-framework

我正在尝试将图像从客户端应用程序上传到我的 django 网络服务器。我正在尝试使用 NSURLConnection 创建与以下curl 命令等效的命令。

curl -v  -S  -X POST  -H 'Accept: application/json' -F image=@"//Users/mackaiver/someImageOfACat.jpg;type=image/jpg"  -F kiosk="81" http://myurl.de/rest/image/ 

预期的响应是 HTTP Status 201 Created,并且我认为服务器确实期望某种 JSON 响应。当我使用这样的 curl 线时

curl -v  -S  -X POST  -H 'Accept: application/json' -F image=@"//Users/mackaiver/someImageOfACat.jpg;type=image/jpg" http://myurl.de/rest/image/

我预计会收到 400 Bad Request 响应。到目前为止,一切都很好。通过命令行上的curl 可以正常工作。 现在我想在 iOS 中做到这一点。到目前为止,我想我可以使用以下代码来发送图像。

NSString *urlString = [ NSString stringWithFormat:@"%@image",REST_BASE_URL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:@"POST"];

NSData *imageData = UIImageJPEGRepresentation(image, 1.0);


NSString *boundary = @"----------------------------6f875f2289c9";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];

NSMutableData *body = [NSMutableData data];

// file
[body appendData:[[NSString stringWithFormat:@"--%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Disposition: attachment; name=\"image\"; filename=\"image_upload.jpg\"\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@"Content-Type: application/octet-stream\r\n\r\n" dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];
[body appendData:[[NSString stringWithFormat:@"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

现在,由于某种原因,这会创建一个 200 OK 响应,这根本不是我所期望的。我也不知道如何添加 kiosk=81 参数。有什么办法可以做到这一点吗?我应该使用像 AFNetworking 这样的外部库吗?

提前致谢:)

编辑:

这就是我的代码现在的样子。查看curl 命令和我的应用程序的wireshark 输出,我似乎找不到任何差异。

NSString *urlString = [ NSString stringWithFormat:@"%@image",BASE_URL];

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:urlString]];


NSString *boundary = @"--6ee875e2289c9";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@", boundary];
NSString *accept = @"application/json";

[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
[request setValue:accept forHTTPHeaderField: @"Accept"];
[request setHTTPMethod:@"POST"];


NSMutableData *body = [NSMutableData data];

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

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

[body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];

[request setHTTPBody:body];
self.connection = [[NSURLConnection alloc]
                   initWithRequest:request
                   delegate:self];

最佳答案

您的 Django Web 服务需要 multipart/form-data请求:

  • 一个Accept: application/json自定义 header 字段,
  • imagekiosk参数。

借助以下选项,您知道如何通过命令行使用curl 来实现此目的:

  1. -H/--header <line>设置您的自定义 header ,
  2. -X POST发出POST请求,
  3. -F/--form <name=content>指定多部分 POST 数据。

在 Objective-C 中使用 NSURLConnectionNSURLRequest您需要执行与上述选项相同的操作:

  1. 您可以在 NSURLRequest 上设置自定义 header 实例感谢 addValue:forHTTPHeaderField:方法,
  2. 您可以执行POST请求通过 [request setHTTPMethod:@"POST"]; ,
  3. 您需要设置格式正确的body字符串 [request setHTTPBody:body]; .

所以问题是:如何使用我的图像和信息亭参数手动创建多部分/表单数据正文字符串?

RFCcurl --trace-ascii out.txt ...可以帮助您构建主体(请注意,您需要 2 个边界部分,因为您有 2 个参数)。

或者,您可以轻松找到许多有关如何执行此操作的示例,例如:Sending Multipart Forms with Objective-C .

最后,AFNetworking是 NSURLConnection 的一个方便的包装器。它特别方便,因为它提供了即用型 multipartFormRequestWithMethod 用于执行多部分 POST 请求的方法。因此您可以使用它作为替代方案。

关于ios - 使用一个 NSURL 请求发布图像和 JSON 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18803565/

相关文章:

ios - 核心数据和谓词

python - 导入单个 Django 设置常量以避免完整设置导入开销的正确方法?

Django 和 Bootstrap : offline reload page issue (netdna. bootstrapcdn.com)

java - 如何告诉 jackson 将 "null"字符串反序列化为空文字?

javascript - 无法使用 $http 读取 json 文件

ios - 在 iOS 上从 SecKeyRef 生成 PKCS12 key

ios - 从 UITabBarController 内部呈现 UINavigationController

Django 1.5 : UserCreationForm & Custom Auth Model

javascript - 在 Ajax 调用中传递 Json.Net 对象

ios - SWRevealViewController - 在@IBAction 下手动显示它