我正在尝试将图像从客户端应用程序上传到我的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 -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];
答案 0 :(得分:3)
您的Django Web服务需要multipart/form-data请求:
Accept: application/json
自定义标题字段image
和kiosk
参数。您知道如何使用curl从命令行实现此功能,这要归功于以下选项:
-H/--header <line>
设置您的自定义标题-X POST
发出POST
请求,-F/--form <name=content>
指定多部分POST数据。 在使用NSURLConnection
和NSURLRequest
的Objective-C中,您需要执行与上述选项相同的操作:
NSURLRequest
方法在addValue:forHTTPHeaderField:
个实例上设置自定义标题,POST
,[request setHTTPMethod:@"POST"];
请求
body
设置格式正确的[request setHTTPBody:body];
字符串。所以问题是:如何使用我的图像和信息亭参数手动创建multipart / form-data正文字符串?
RFC和curl --trace-ascii out.txt ...
可以帮助您构建正文(请注意,由于您有2个参数,因此需要2个边界部分。)
或者,您可以轻松找到许多样本,例如:Sending Multipart Forms with Objective-C。
最后,AFNetworking是NSURLConnection的一个方便的包装器。它特别方便,因为它提供了一个用于执行多部分POST请求的即用型multipartFormRequestWithMethod
方法。因此,您可以将其作为替代方案。