Cocoa HTTP POST请求[Mac OS X]

时间:2012-01-30 14:41:26

标签: html cocoa xmlhttprequest http-post httpresponse

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

我发现一些看起来不错的代码。我改变它就像它符合我的需要。但代码不起作用,我找不到bug,因为我对可可很新。

这是我的代码。

- (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消息是“web request started”和“connection initiated”。 所以我认为不会调用- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

有人可以帮我解决这个问题吗?

感谢您的帮助,Julian

2 个答案:

答案 0 :(得分:7)

你几乎正确地做到了!

我可以看到该帖子已有一年的历史,但希望它可以帮助其他人并且我自己参考,我在这里发帖。

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);
}

答案 1 :(得分: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"];

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