从Cocoa发送POST表单

时间:2010-09-10 14:16:14

标签: cocoa macos

嘿所有人!我从http://deusty.blogspot.com/2006/11/sending-http-get-and-post-from-cocoa.html读了一篇文章,但我没有得到一些东西。我尝试用它来建立NSURLConnection,以及它根本不会接收数据?如果您对此感兴趣,请访问www.lockerz.com网站。

http://pastebin.com/8fP9TX8q。修复链接,因为我不能发布超过1个。

它实际上说连接失败了,我不知道为什么......

1 个答案:

答案 0 :(得分:7)

问题#1

突然出现的错误是前两行:

NSString *post = @"email-email=test@email.com&password-password=testpassword";
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];

提交POST表单(以及URL中的GET参数)时,只应对键和值进行URL编码。在这里,您不仅要对键和值进行编码,还要对=&进行编码,这是完全错误的。我通常做这样的事情:

NSMutableDictionary * parameters = [NSMutableDictionary dictionary];
[parameters setObject:@"test@email.com" forKey:@"email-email"];
[parameters setObject:@"testpassword" forKey:@"password-password"];

NSMutableArray * encodedParameters = [NSMutableArray array];
for (NSString * key in parameters) {
  NSString * value = [parameters objectForKey:key];
  NSString * encoded = [NSString stringWithFormat:@"%@=%@", [key stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding], [value stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
  [encodedParameters addObject:encoded];
}

NSString * post = [encodedParameters componentsJoinedByString:@"&"];
NSData * postData = [post dataUsingEncoding:NSASCIIStringEncoding];

使用stringByAddingPercentEscapesUsingEncoding:也可能会遇到问题。我写了一个关于如何对字符串here进行URL编码的NSString类别。

问题#2

您永远不会等待连接发送。 NSURLConnection就像你使用它一样,是一个异步 API。因此,以下内容将失败:

NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
if (theConnection) {
  NSLog(@"Connection succeeded!");
}

您正在测试的是没有成功完成连接,而是成功连接对象的实例化。这是一个非常不同的事情。连接本身实际上可能无法完成运行循环的几次旋转。如果您希望连接是同步的(即,在执行下一行代码之前完成连接),则需要使用NSURLConnection's synchronous API

问题#3

这些行充满了失败:

receivedData = [[NSMutableData data] retain];
NSString *text = [[NSString alloc] initWithData:receivedData encoding:NSASCIIStringEncoding];

[NSMutableData data]返回一个空数据对象。 它什么都没有。因此,如果您创建一个空数据对象,然后从数据中创建一个字符串,那么(惊喜)您将得到一个空字符串。

另外你正在泄漏数据对象(因为你retain它[这是不必要的],但从来没有release它。

编辑,因为我感觉很慷慨......

以下工作正常(虽然我只是硬编码HTTPBody字符串而不是按照上面的建议构建它):

NSURL * url = [NSURL URLWithString:@"http://www.lockerz.com/auth/login/"];
NSMutableURLRequest * r = [[NSMutableURLRequest alloc] initWithURL:url];
[r setHTTPMethod:@"POST"];
[r setHTTPBody:[@"email%2Demail=test%40email%2Ecom&password%2Dpassword=testpassword" dataUsingEncoding:NSASCIIStringEncoding]];
[r setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

NSHTTPURLResponse * response = nil;
NSError * error = nil;
NSData * responseData = [NSURLConnection sendSynchronousRequest:r returningResponse:&response error:&error];
NSString * responseString = [[[NSString alloc] initWithData:responseData encoding:NSASCIIStringEncoding] autorelease];
NSLog(@"%@", responseString);
[r release];

这正确执行,responseString记录一些描述错误页面的HTML。但是,这并不令人惊讶,因为URL本身(http://www.lockerz.com/auth/login)在尝试使用原始问题中提供的凭据时会产生错误。

相关问题