Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/http/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将映像发布到服务器iOS不工作_Ios_Http_Post - Fatal编程技术网

将映像发布到服务器iOS不工作

将映像发布到服务器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

我正试图在我的ipad上向iOS服务器发出post请求。我已经跟随并尝试了多个发布的示例,但我仍然无法让它工作。post请求总是使用200状态代码和HTML页面进行响应,但根据API和API的创建者,它应该使用json进行响应。我收到了一个有效的POST请求示例。下面是我用来发送照片的函数

-(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:@"+"];
}