使用一个NSURL请求发布图片和JSON数据 [英] Post image and JSON data with one NSURLrequest

查看:186
本文介绍了使用一个NSURL请求发布图片和JSON数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试从客户端应用程序上传图像到我的django网络服务器。我尝试使用NSURLConnection创建相当于以下curl命令。

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

预期的响应是HTTP状态201已创建,服务器确实需要某种JSON响应。当我使用这样的卷曲线

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

我预计会有400个错误请求。到现在为止还挺好。这通过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];

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

现在由于某种原因,这会创建一个200 OK响应,这根本不是我预期的。我也不知道如何添加kiosk = 81参数。有什么办法吗?





编辑:



这是我的代码现在的样子。看看我的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\\\
- %@ \r\\\
,boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[[NSString stringWithFormat:@Content-Disposition:form-data; name = \image\; filename = \bla.jpg\\r\\\
] dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[@Content-Type:image / jpg\r\\\
\r\\\
dataUsingEncoding:NSUTF8StringEncoding]];
[body appendData:[NSData dataWithData:imageData]];

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

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

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


解决方案

您的Django Web服务期望 multipart / form-data 请求与:




  • a 接受:application / json 自定义标题字段,




您知道吗?

如何用curl实现这一点,从命令行,感谢以下选项:


  1. -H / -header< line> 以设置您的自定义标题

  2. -X POST code> POST 请求,

  3. -F / - form< name = content> 以指定多部分POST数据。

在Objective-C中使用 NSURLConnection NSURLRequest 您需要执行上述选项的等效操作:


  1. 通过 addValue:forHTTPHeaderField:方法,

  2. ,您可以执行c $ c> c $ c> NSURLRequest POST 通过请求[request setHTTPMethod:@POST];

  3. 您需要使用 [request setHTTPBody:body];
  4. $设置正确格式化的正文所以问题是:如何使用我的图片和kiosk参数手动创建一个multipart / form-data body字符串?



    RFC curl --trace-ascii out.txt ... 可以帮助你构建身体(注意,你需要2个边界节,因为你有2个参数)。



    或者你可以很容易地找到很多样本,例如:使用Objective-C发送多部分表单



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


    Im trying to upload an image from the client application to my django webserver. Im trying to create the equivalent of the following curl command using NSURLConnection.

    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/ 
    

    The expected response is the HTTP Status 201 Created and the server does expect some sort of JSON response I presume. When I use a curl line like this

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

    I expect a 400 Bad Request respone. So far so good. This works fine via curl on the command line. Now I want to do this in iOS. So far Im thinking I can use following code to send an image.

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

    Now for some reason this creates a 200 OK response which is not at all what I expected. Also I dont know how to add the kiosk=81 parameter. Is there any way to do this? Should I use an external library like AFNetworking?

    Thanks in advance :)

    EDIT:

    This is what my code looks like now. Looking at the wireshark output from both the curl command and my app I cant seem to find any differences.

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

    解决方案

    Your Django web service expects a multipart/form-data request with:

    • a Accept: application/json custom header field,
    • image and kiosk parameters.

    You know how to achieve this with curl, from the command line, thanks to the following options:

    1. -H/--header <line> to set your custom header,
    2. -X POST to issue a POST request,
    3. -F/--form <name=content> to specify multipart POST data.

    In Objective-C with NSURLConnection and NSURLRequest you need to do the equivalent of the above options:

    1. you can set a custom header on your NSURLRequest instance thanks to the addValue:forHTTPHeaderField: method,
    2. you can perform a POST request via [request setHTTPMethod:@"POST"];,
    3. you need to set a properly formatted body string with [request setHTTPBody:body];.

    So the question is: how do I manually create a multipart/form-data body string with my image and kiosk parameters?

    The RFC and curl --trace-ascii out.txt ... may help you building the body (note that you need 2 boundary sections since you have 2 parameters).

    Alternatively you can easily find many samples on how to do that, e.g: Sending Multipart Forms with Objective-C.

    At last, AFNetworking is a convenient wrapper around NSURLConnection. It is particularly handy since it provides a ready-to-use multipartFormRequestWithMethod method used to perform multipart POST requests. So you can use it as an alternative.

    这篇关于使用一个NSURL请求发布图片和JSON数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆