将映像发布到服务器iOS不工作
我正试图在我的ipad上向iOS服务器发出post请求。我已经跟随并尝试了多个发布的示例,但我仍然无法让它工作。post请求总是使用200状态代码和HTML页面进行响应,但根据API和API的创建者,它应该使用json进行响应。我收到了一个有效的POST请求示例。下面是我用来发送照片的函数将映像发布到服务器iOS不工作,ios,http,post,Ios,Http,Post,我正试图在我的ipad上向iOS服务器发出post请求。我已经跟随并尝试了多个发布的示例,但我仍然无法让它工作。post请求总是使用200状态代码和HTML页面进行响应,但根据API和API的创建者,它应该使用json进行响应。我收到了一个有效的POST请求示例。下面是我用来发送照片的函数 -(IBAction)testSendPhoto:(id)sender { NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocument
-(IBAction)testSendPhoto:(id)sender
{
NSString *docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSMutableArray * currentFormPictures = [NSMutableArray arrayWithArray:appDelegate.pictures[appDelegate.currentForm]];
NSString * pictureFilePath = currentFormPictures[0];
NSLog(@"Sending picture:%@", pictureFilePath);
NSString *filename =[pictureFilePath stringByReplacingOccurrencesOfString:[docDir stringByAppendingString:@"/"] withString:@""];
UIImage * pictureFile = [[UIImage alloc] initWithContentsOfFile:pictureFilePath];
NSData *imageData = UIImageJPEGRepresentation(pictureFile, 1.0f);
NSMutableString * urlString = [NSMutableString stringWithString:@"http://urlForSite.com/?format=json"];
[urlString appendString:@"&username="];
[urlString appendString:appDelegate.username];
[urlString appendString:@"&api_key="];
[urlString appendString:appDelegate.apikey];
NSURL *url = [NSURL URLWithString:urlString];
NSLog(@"Sending it to URL: %@", urlString);
NSMutableURLRequest * request= [[NSMutableURLRequest alloc] init];
[request setURL:url];
[request setHTTPMethod:@"POST"];
NSString *boundary = @"----WebKitFormBoundaryE19zNvXGzXaLvS5C";
NSString *contentType = [NSString stringWithFormat:@"form-data; boundary=%@",boundary];
[request setValue:contentType forHTTPHeaderField: @"Content-Type"];
NSMutableData *postbody = [NSMutableData data];
[postbody appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithFormat:@"Content-Disposition: form-data; name=\"file\"; filename=\"%@\"\r\n", filename] dataUsingEncoding:NSUTF8StringEncoding]];
[postbody appendData:[[NSString stringWithString:@"Content-Type: image/jpeg\r\n\r\n"] dataUsingEncoding:NSUTF8StringEncoding]];
NSLog(@"Post Body:%@", [[NSString alloc] initWithData:postbody encoding:NSUTF8StringEncoding]);
[postbody appendData:imageData];
[postbody appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
[request setHTTPBody:postbody];
//NSString *postLength = [NSString stringWithFormat:@"%lu", (unsigned long)[postbody length]];
//[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
API创建者给出的工作示例:
POST /warehouse/apiTempFileUploader/?format=json&username=admin&api_key=c67332f5596301f598c1807a6767a048ed1d17d9 HTTP/1.1
Host: localhost:8001
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="file"; filename="GPSEXIF.jpg"
Content-Type: image/jpeg
----WebKitFormBoundaryE19zNvXGzXaLvS5C
我也用过
NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
作为内容类型,但仍然没有运气。在API创建者的建议下,我也删除了标题,但运气不好
-使用didReceiveResponse、didReceiveData和ConnectiondFinishLoading更新
(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
responseData = [NSMutableData data];
NSLog(@"Response from connection: %@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
NSDictionary * headers = [(NSHTTPURLResponse *)response allHeaderFields];
statusCode = (int)[(NSHTTPURLResponse *)response statusCode];
NSLog(@"headers: %@", headers);
NSLog(@"Status code: %d", statusCode);
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
[responseData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString * responseJson = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData: [responseJson dataUsingEncoding:NSUTF8StringEncoding]
options: NSJSONReadingMutableContainers
error: nil];
NSLog(@"JSon: %@", JSON);
NSLog(@"response data - %@", responseJson);
}
应为@multipart/表单数据;边界=%@
更新
我看到你的最新消息了。必须包含多部分/表单数据的内容类型
见和
更新2
我不确定您对URL更改了多少,但在提供的代码中,您没有路径
NSMutableString * urlString = [NSMutableString stringWithString:@"http://urlForSite.com/?format=json"];
其中,与示例中一样,路径是/warehouse/apistemfileuploader/
您是否尝试过:
NSMutableString * urlString = [NSMutableString stringWithString:@"http://urlForSite.com/warehouse/apiTempFileUploader/?format=json"];
此外,您可能需要添加
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
告诉服务器您正在接受JSON响应。请求的主要部分肯定应该是多部分/表单数据,而不仅仅是表单数据 此外,如果您在文件的部件中再添加一个头,也会有所帮助。该标题应为: 内容传输编码:二进制 最后一点观察,您的代码几乎是完美的。下面的HTTP示例不正确。边界应该在每个部分的开头有一个-前缀,在请求的结尾有一个额外的-后缀
我最近写了一篇文章,就是为了你想做的事,这可能会有所帮助。我建议在中检查请求,以确保请求看起来像它应该做的那样。以下是几点观察: 它肯定是多部分/表单数据,而不仅仅是表单数据 您说的不是接收JSON响应,而是接收站点基本页面模板的html页面 对于返回JSON的页面来说,返回HTML页面是非常不寻常的。如果存在阻止API开发人员代码运行的基本问题,例如基本身份验证错误或URL本身不正确,则可能发生这种情况。我打赌,如果你告诉你的API开发人员你收到了什么样的HTML响应,他/她可能会帮助你诊断出哪里出了问题 与您当前的挑战无关: 我不建议使用本身以破折号开头的边界。我不认为这会导致问题,但当您开始调试请求时,它只会让您感到困惑。因为您的边界包含四个破折号,所以您将在请求中看到六个破折号。这似乎是不必要的混乱 我很惊讶用户名和api_密钥是URL的一部分,因为这是不安全的。您向我们保证,您已经确认这是API设计所需要的,但是一旦您解决了这个直接问题,您真的应该向API开发人员提出这个主题,因为在URL中添加身份验证详细信息是不谨慎的。图像数据以及用户名和api_键都应该在请求主体中得到它们自己的部分,而不是出现在URL本身中 您真的不想在UIImage中来回使用pictureFilePath。只需使用dataWithContentsOfFile并直接获取数据,然后发送即可。UIImageJPEGRepresentation很可能会生成与原始图像不同的有效负载,如果系数为1.0f,则可能比原始文件大,如果小于1.0f,则可能会导致图像降级。除非您有明确的理由通过UIImage往返于此,否则您不应该这样做 如果用户用户名或api密钥可能包含保留字符,例如+或&或空格,则在将这些值添加到URL之前,您确实需要对其进行%转义。并且,请注意,不要使用StringByAddingPercentEscapeSusingEncode,而是使用CFURLCreateStringByAddingPercentEscapes: 如果在多部分/表单数据请求中指定了该值,则不需要这样做,但如果在URL中或在应用程序/x-www-form-urlencoded请求中指定了该值,则需要进行百分比转义
什么是响应?我得到了该站点基本页面的HTML代码的响应。菜单栏和诸如此类的策略,NSMutableString*urlString=[NSMutableString stringWithString:@;是我正在使用的url。我目前没有发布该url的权限。能否更具体地说明我缺少-。我在第一个边界之前和最后一个边界之前和之后都有它们。我将尝试从零开始使用您文章中的示例。这在HTTP示例中,在API创建者给出的短语工作示例。代码是正确的,代码下的示例是错误的。哦,我明白了。我会向开发人员询问。我确信
e用户名和api密钥应位于URL中。我有其他帖子,它们只是文本json主体,用于其他具有类似URL的API调用。我还没有实现didFailWithError。我将把我的didReceiveData和ConnectiondFinishLoading添加到我的原始问题中,它们主要由日志记录组成。我将实现didFailWithError并查看我得到了什么。responseJson作为网站基本页面模板的html页面返回。在查看了我在Charles中的请求后,我开始怀疑API是否正常工作。我要和开发商联系。
NSMutableString * urlString = [NSMutableString stringWithString:@"http://urlForSite.com/warehouse/apiTempFileUploader/?format=json"];
[request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
/** Percent escape string
*
* Note, this does not use `stringByAddingPercentEscapesUsingEncoding`, because
* that that will not percent escape some critical reserved characters (notably
* `&` and `+`). This uses `CFURLCreateStringByAddingPercentEscapes`, instead.
*/
- (NSString *)percentEscapeString:(NSString *)string
{
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)string,
(CFStringRef)@" ",
(CFStringRef)@":/?@!$&'()*+,;=",
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}