【问题标题】:Cocoa HTTP POST Request [Mac OS X]Cocoa HTTP POST 请求 [Mac OS X]
【发布时间】:2012-01-30 14:41:26
【问题描述】:

我花了很多时间研究使用 Cocoa 的 POST 请求。

我发现了一些看起来不错的代码。我改变了它,就像它适合我的需要一样。但是代码不起作用,我找不到错误,因为我对可可很陌生。

这是我的代码。

- (IBAction)sendForm:(id)sender
{
    NSLog(@"web request started");
    NSString *post = [NSString stringWithFormat:@"firstName=%@&lastName=%@&eMail=%@&message=%@", firstName.stringValue, lastName.stringValue, eMail.stringValue, message.stringValue];
    NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
    NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];

    NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
    [request setURL:[NSURL URLWithString:@"myDomain/form.php"]];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];

    NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if(theConnection)
    {
        webData = [[NSMutableData data] retain];
        NSLog(@"connection initiated");
    }
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [webData appendData:data];
    NSLog(@"connection received data");
}
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    NSLog(@"connection received response");
    NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response;
    if([ne statusCode] == 200)
    {
        NSLog(@"connection state is 200 - all okay");
        NSString *html = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
        [[webView mainFrame] loadHTMLString:html baseURL:[NSURL URLWithString:@"myDomain"]];
    }
}

但我收到的仅有的两条 NSLog 消息是“网络请求已启动”和“连接已启动”。 所以我认为- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 和- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 没有被调用。

谁能帮我解决这个问题?

谢谢你的帮助,朱利安

【问题讨论】:

    标签: html cocoa xmlhttprequest http-post httpresponse


    【解决方案1】:

    你几乎做对了!

    我可以看到这篇文章已经有一年了,但希望它可以帮助其他人并作为我自己的参考,我在这里发布。

    Apple 的 connection:didReceiveResponse: 文档说:-

    当连接接收到足够的数据来构建 其请求的 URL 响应。

    与大多数 Apple 文档一样,这也令人困惑并且可能具有误导性。通常当我们有“足够的数据来构造 URL 响应”意味着我们有完整的响应,这进一步意味着我们也有响应体;这被普遍认为是响应的一部分。

    但是在这种情况下,NSHTTPURLResponse 对象没有主体。所以我的猜测是,Apple 的意思是——connection:didReceiveResponse: 在我们收到包含“足够”数据的响应头时被调用,让我们知道除了实际数据(正文)之外的所有关于响应的信息。

    事实上很多时候你会注意到connection:didReceiveData:在connection:didReceiveResponse:被调用之后被调用。

    所以,我们可以修改您的代码如下:-

    - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    
        NSLog(@"web request started");
        NSString *post = [NSString stringWithFormat:@"firstName=%@&lastName=%@&eMail=%@&message=%@", firstName.stringValue, lastName.stringValue, eMail.stringValue, message.stringValue];
        NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
        NSString *postLength = [NSString stringWithFormat:@"%ld", (unsigned long)[postData length]];
    
        NSLog(@"Post data: %@", post);
    
        NSMutableURLRequest *request = [NSMutableURLRequest new];
        [request setURL:[NSURL URLWithString:@"https://example.com/form.php"]];
        [request setHTTPMethod:@"POST"];
        [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setHTTPBody:postData];
    
        NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    
        if(theConnection) {
            webData = [NSMutableData data];
            NSLog(@"connection initiated");
        }
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
        [webData appendData:data];
        NSLog(@"connection received data");
    }
    
    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
        NSLog(@"connection received response");
        NSHTTPURLResponse *ne = (NSHTTPURLResponse *)response;
        if([ne statusCode] == 200) {
            NSLog(@"connection state is 200 - all okay");
        } else {
            NSLog(@"connection state is NOT 200");
        }
    }
    
    -(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
        NSLog(@"Conn Err: %@", [error localizedDescription]);
    }
    
    - (void)connectionDidFinishLoading:(NSURLConnection *)connection {
        NSLog(@"Conn finished loading");
        NSString *html = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
        NSLog(@"OUTPUT:: %@", html);
    }
    

    【讨论】:

      【解决方案2】:

      您是否尝试过实现错误委托方法?

      - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
          // do something with error
      }
      

      在NSURLConnection 能够建立连接之前,您可能没有互联网连接,或者出现其他问题。在这种情况下,您将不会收到 http 响应或任何其他数据。该错误将提供更多信息。

      [编辑]

      我刚刚注意到示例代码中的 URL 不包含主机名。如果这是您使用的确切代码,请确保将请求发送到正确的 URL。

      // Replace
      [NSURL URLWithString:@"myDomain/form.php"]
      // with a correct url like
      [NSURL URLWithString:@"http://mydomain.com/form.php"];
      

      错误委托方法实际上会为您提供一个抱怨错误 URL 的错误。

      【讨论】:

      • 事实上,即使您提供了有效的域但没有提供协议(“http://”),对 +URLWithString: 的调用也将返回 nil。这意味着您将请求的 URL 设置为 nil。
      • 我的代码肯定有其他问题。 mydomain 我的意思是使用领先协议的外部 IP 地址。所以这不是问题。而didFailWithError 甚至没有被调用!我输入了NSLog("error"); 来测试该功能。但是Log没有输出任何东西
      猜你喜欢
      • 1970-01-01
      • 2011-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-19
      • 2013-01-30
      相关资源
      最近更新 更多