cocoa - 从 Cocoa 发送 POST 表单

标签 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

前两行立即让我觉得错误:

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:时也可能会遇到问题。我写了一个关于如何对字符串进行 URL 编码的 NSString 类别 here .

问题#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] 返回一个空数据对象。 它什么都不包含。因此,如果您创建一个空数据对象,然后从数据中创建一个字符串,那么(令人惊讶的是)您将得到一个空字符串。

另外,您正在泄漏数据对象(因为您保留它[这是不必要的],但从不释放它)。

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

以下内容可以正常工作(尽管我只是硬编码了 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 ) 会产生错误。

关于cocoa - 从 Cocoa 发送 POST 表单,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3685302/

相关文章:

swift - NSInputStream/NSOutputStream 未打开

cocoa - cocoa 的面包屑导航

c++ - 检测到子进程因操作系统内存不足而被终止

Python + Django : Trouble with setting up mkvirtualenv on macOS

macos - 为内存加密密码是否过度?

linux - 突然我收到错误 "cannot read termcap database"

objective-c - 在 objc_SetAssociatedObject 中使用非 id 指针作为值是否可以?

objective-c - 如何在 Xcode 中正确布局独立的系统服务?

objective-c - NSNotification/绑定(bind)?

macos - 在几个 NSTableviews 中呈现字典