【问题标题】:Turn this .php into ObjC runnable NSURLSession POST requests?将此 .php 转换为 ObjC 可运行的 NSURLSession POST 请求?
【发布时间】:2014-03-21 18:52:02
【问题描述】:

基本上,我正在尝试登录这个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) 和密码 (wildcats) 进行身份验证并返回带有 {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");
        }
    }];

谁能告诉我代码中的问题出在哪里?

【问题讨论】:

    标签: php ios http post nsurl


    【解决方案1】:
    1. 通常,您需要指定请求的Content-type (application/x-www-form-urlencoded)。

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

    3. 1234563 /p>
    4. 您需要指定您的请求是POST 请求。所以,使用原来的NSMutableURLRequest 并正确配置它,然后停用你的NSURLRequest

    5. 你不希望那一行写着:

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

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

    因此,您最终会得到以下结果:

    - (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"];
    

    【讨论】:

    • 好的,它不适用于content type:content/x-www-form-urlencoded,所以我注释掉了那一行,它返回了 Response is = { msg = "";有效 = 1;喜欢它。
    • 现在我已经“登录”了,如何留在同一个会话中并转到另一个页面?我是否只是将另一个异步请求添加到队列中?这是否意味着我仍在登录?
    • @AndrewSB Re the content-type,应该是 application/x-www-form-urlencoded,正如我在第一个要点中提到的那样。对不起,代码示例中的错字。不过,我已经相应地编辑了我的答案,它只取决于服务器代码的预期。关于登录状态,这也取决于服务器代码的编写方式。服务器通常会使用 cookie,而且它是无缝的。再次与该服务器代码的作者核实(或查看[(NSHTTPURLResponse *)response allHeaderFields] 字典)。但通常你只需发出另一个sendAsynchronousRequest
    【解决方案2】:

    以下行不正确。

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

    "&lt;input type=text name='Pin'&gt; &lt;input type=password name='Password'&gt; &lt;input type='submit' id='LoginButton'&gt;" 不是正确的 POST 字符串

    你需要用类似"Pin=20005012&amp;Password=wildcats"的东西替换它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-14
      • 2019-10-11
      相关资源
      最近更新 更多