通过Objective-C HTTP Post上传照片

3
我正在发送一张图片,构建HTTP POST请求如下:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setHTTPShouldHandleCookies:NO];
[request setTimeoutInterval:30];
[request setHTTPMethod:@"POST"];


NSString *boundary = @"801f6dd4cd17";
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data;boundary=------------------------------%@", boundary];


NSMutableDictionary *headerFieldsDict = [[ NSMutableDictionary alloc] init];
[ headerFieldsDict setObject:contentType forKey:@"Content-Type"];

[request setAllHTTPHeaderFields:headerFieldsDict];

NSMutableData *body = [NSMutableData data];

//---------- FIRST IMG
UIImage* imgLittle = [realImgButton imageForState:UIControlStateNormal];//thumImg.image;
NSData *imageData = UIImageJPEGRepresentation(imgLittle, 1.0);
if (imageData) {
    [body appendData:[[NSString stringWithFormat:@"------------------------------%@\r\n", boundary] dataUsingEncoding:NSUTF8StringEncoding]];


    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"img.jpg\"\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];


    [body appendData:[[NSString stringWithString:@"Content-Type: application/octet-stream\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];

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

[request setHTTPBody:body];

但是服务器拒绝上传图像(它给出一个软件错误,似乎HTTP post没有被很好地解析),我所知道的关于服务器的唯一信息是这个php客户端代码可以正常工作:

$data['file'] = "@".$file;
$header[] = "Expect: ";
print_r($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header );

//curl_setopt($ch, CURLOPT_URL, 'http://xxxxxx:yyy/');
curl_setopt($ch, CURLOPT_ENCODING, 'gzip,deflate');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);
$xml = simplexml_load_string($response);
$url = strip_tags($xml->dict->string[3]->asXML());
return $url;

有什么想法吗?或者我的obj-c代码哪里出错了?我试图分析产生的HTTP POST语句,看起来与PHP代码产生的相同。

4个回答

0

你可能想使用-addValue:forHTTPHeaderField:而不是这样做:

NSMutableDictionary *headerFieldsDict = [[ NSMutableDictionary alloc] init];
[ headerFieldsDict setObject:contentType forKey:@"Content-Type"];

[request setAllHTTPHeaderFields:headerFieldsDict];

你所需要做的就是向请求添加一个单独的头部,但是上面的代码实际上会清除任何现有的头部。

这是不正确的,我嗅探了HTTP Post并且输出结果如下:http://pastebin.com/hdjgdXU5。我尝试使用PHP代码具有相同的标头,上传工作正常... - Kerby82

0

我不确定你的代码问题出在哪里,但我有两个想法:

  1. 我认为你在 Content-Disposition 结尾处可能需要另一个 \r\n ,像这样:

    [body appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"image\"; filename=\"img.jpg\"\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
    
  2. 使用 UIImageJPEGRepresentation 并将内容类型设置为 application/octet-stream 可能是问题所在。对于 application/octet-stream[NSData dataWithContentsOfFile:] 可能更合适,而 image/jpeg 可能更适合于 UIImageJPEGRepresentation。不过这只是猜测。

如果您确实遇到了困难,您可以使用AFNetworking(它比ASIHTTPRequest更加现代化且轻量级)。或者,您至少可以查看它们的代码,以了解它们如何处理文件上传。

0
你发布的代码看起来很熟悉,所以我检查了一个旧应用程序,在那里我一直在POST图像,我们显然从同一来源获取了代码(我不记得是哪个)。我的代码几乎完全相同,除了边界字符串和我去掉了多余的[NSString stringWithFormat:]
[request setHTTPMethod:@"POST"];

NSString *boundary = @"0xKhTmLbOuNdArY"; 

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",boundary] dataUsingEncoding:NSUTF8StringEncoding]];

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

[request setHTTPBody:body];

这段代码在我的机器上运行良好,所以假设您的图像数据没有问题,那么您需要检查一下边界。我的图像数据也是由UIImageJPEGRepresentation创建的。


0
你可以使用ASIHTTPRequest框架: 在我的一个项目中,我使用它来将图片上传到服务器上。
ASIFormDataRequest *request = [ASIFormDataRequest requestWithURL:yourURL];
[request addPostValue:NSString  forKey:@"KEY"];
[request addPostValue:NSString forKey:@"KEY"];
... any post value you need

[request addData:image withFileName:[name of the file]
    andContentType:@"image/jpeg" forKey:@"KEY"];

希望这可以帮到你 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接