使用一个NSURL请求发布图片和JSON数据 [英] Post image and JSON data with one NSURLrequest
问题描述
我尝试从客户端应用程序上传图像到我的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实现这一点,从命令行,感谢以下选项:-
-H / -header< line>
以设置您的自定义标题 -
-X POST
code> POST 请求, -
-F / - form< name = content>
以指定多部分POST数据。
在Objective-C中使用 NSURLConnection
和 NSURLRequest
您需要执行上述选项的等效操作:
- 通过
addValue:forHTTPHeaderField:
方法, - ,您可以执行c $ c> c $ c> NSURLRequest
POST
通过请求[request setHTTPMethod:@POST];
, - 您需要使用
[request setHTTPBody:body];
。 $设置正确格式化的 - a
Accept: application/json
custom header field, image
andkiosk
parameters.-H/--header <line>
to set your custom header,-X POST
to issue aPOST
request,-F/--form <name=content>
to specify multipart POST data.- you can set a custom header on your
NSURLRequest
instance thanks to theaddValue:forHTTPHeaderField:
method, - you can perform a
POST
request via[request setHTTPMethod:@"POST"];
, - you need to set a properly formatted
body
string with[request setHTTPBody:body];
.
正文
所以问题是:如何使用我的图片和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:
You know how to achieve this with curl, from the command line, thanks to the following options:
In Objective-C with NSURLConnection
and NSURLRequest
you need to do the equivalent of the above options:
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屋!