将此.php转换为ObjC可运行的NSURLSession POST请求?

时间:2014-03-21 18:52:02

标签: php ios http post nsurl

基本上,我正在尝试登录此website called Mistar。我可以用php做到这一点:

<form action="https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login" method="post">
<input type=text name="Pin">
<input type=password name="Password">
<input type="submit" id="LoginButton">
</form>

所以php(当你运行它)工作。您使用它验证的Pin(20005012)和密码(野猫)并返回一个类似{1, User Authenticated}

的页面

现在我要做的是从iPhone应用程序(所以ObjC)登录网站,可能使用NSURLSession或其他东西。

这是我到目前为止所做的,但它一直给我一个错误:登录页面:

- (void)loginToMistar {

    //Create POST request
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];

    //Create and send request
    NSURL *url = [NSURL URLWithString:@"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    NSString *postString = [NSString stringWithFormat:@"<input type=text name='Pin'> <input type=password name='Password'> <input type='submit' id='LoginButton'>"];
    NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
    [request setHTTPBody:postBody];

 //   [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    NSString* url=[NSString stringWithFormat:url];

    [NSURLConnection sendAsynchronousRequest:urlRequest queue:queue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
    {
        // do whatever with the data...and errors
        if ([data length] > 0 && error == nil) {
            NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
            NSLog(loggedInPage);
        }
        else {
            NSLog(@"error");
        }
    }];

有人可以告诉我代码中的问题在哪里吗?

2 个答案:

答案 0 :(得分:3)

  1. 通常,您需要指定Content-type请求(application/x-www-form-urlencoded)。

  2. 您希望构建请求的主体以符合该类型的请求(如cmorrissey所述),例如: Pin=xxx&Password=yyy

  3. 您希望确保百分比转义这些值xxxyyy(因为,如果密码包含+之类的任何保留字符,则密码不会正确传播。)

  4. 您需要指定您的请求是POST请求。因此,请使用原始NSMutableURLRequest并正确配置并退出NSURLRequest

  5. 您不希望该行显示:

    NSString* url=[NSString stringWithFormat:url];
    
  6. 您不必创建操作队列。你可以,但是(a)你没有做一些非常慢而且计算成本高的事情; (b)这个完成块可能最终可能想要更新UI,而你永远不会在后台队列中这样做,而只是在主队列中这样做。

  7. 由于响应似乎是JSON,让我们继续解析该响应(如果可以的话)。

  8. 因此,您最终得到的结果如下:

    - (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password {
    
        NSURL *url = [NSURL URLWithString:@"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
    
        //Create and send request
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
    
        [request setHTTPMethod:@"POST"];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-type"];
    
        NSString *postString = [NSString stringWithFormat:@"Pin=%@&Password=%@",
                                [self percentEscapeString:pin],
                                [self percentEscapeString:password]];
        NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
        [request setHTTPBody:postBody];
    
        [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
         {
             // do whatever with the data...and errors
             if ([data length] > 0 && error == nil) {
                 NSError *parseError;
                 NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
                 if (responseJSON) {
                     // the response was JSON and we successfully decoded it
    
                     NSLog(@"Response was = %@", responseJSON);
                 } else {
                     // the response was not JSON, so let's see what it was so we can diagnose the issue
    
                     NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
                     NSLog(@"Response was not JSON, it was = %@", loggedInPage);
                 }
             }
             else {
                 NSLog(@"error: %@", error);
             }
         }];
    }
    
    - (NSString *)percentEscapeString:(NSString *)string
    {
        NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                     (CFStringRef)string,
                                                                                     (CFStringRef)@" ",
                                                                                     (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                     kCFStringEncodingUTF8));
        return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
    }
    

    然后你可以这样称呼它:

    [self loginToMistarWithPin:@"20005012" password:@"wildcats"];
    

答案 1 :(得分:1)

以下行不正确。

NSString *postString = [NSString stringWithFormat:@"<input type=text name='Pin'> <input type=password name='Password'> <input type='submit' id='LoginButton'>"];

因为"<input type=text name='Pin'> <input type=password name='Password'> <input type='submit' id='LoginButton'>"不是正确的POST字符串

您需要将其替换为"Pin=20005012&Password=wildcats"

之类的内容