2014-02-12 26 views
2

我正在開發一個Web服務,並且正在編寫一個註冊/登錄API。當我嘗試在iOS模擬器中註冊時,我得到「預期的內容類型文本/ json獲得了text/html。」我花了幾個小時嘗試調試並發現問題,但沒有看到爲什麼我沒有獲取JSON數據。預期的內容類型text/json得到文本/ html

API.h

#import "AFHTTPClient.h" 
#import "AFNetworking.h" 

typedef void (^JSONResponseBlock)(NSDictionary* json); 

@interface API : AFHTTPClient 

@property (strong, nonatomic) NSDictionary *user; 

+ (API *)sharedInstance; 

//check whether there's an authorized user 
-(BOOL)isAuthorized; 

//send an API command to the server 
-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock; 

@end 

API.m

#import "API.h" 

#define kAPIHost @"http://localhost" 
#define kAPIPath @"/api/" 

@implementation API 

@synthesize user; 

+(API*)sharedInstance 
{ 
    static API *sharedInstance = nil; 
    static dispatch_once_t oncePredicate; 
    dispatch_once(&oncePredicate, ^{ 
     sharedInstance = [[self alloc] initWithBaseURL:[NSURL URLWithString:kAPIHost]]; 
    }); 

    return sharedInstance; 
} 

-(API*)init 
{ 
    //call super init 
    self = [super init]; 

    if (self != nil) { 
     //initialize the object 
     user = nil; 

     [self registerHTTPOperationClass:[AFJSONRequestOperation class]]; 

     // Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 
     [self setDefaultHeader:@"Accept" value:@"application/json"]; 
    } 

    return self; 
} 

-(BOOL)isAuthorized 
{ 
    return [[user objectForKey:@"user_id"] intValue]>0; 
} 

-(void)commandWithParams:(NSMutableDictionary*)params onCompletion:(JSONResponseBlock)completionBlock 
{ 
    NSMutableURLRequest *apiRequest = 
    [self multipartFormRequestWithMethod:@"POST" 
            path:@"http://localhost/api/index.php" 
           parameters:params 
       constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) { 
        //TODO: attach file if needed 
       }]; 

    AFJSONRequestOperation* operation = [[AFJSONRequestOperation alloc] initWithRequest: apiRequest]; 
    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { 
     //success! 
     completionBlock(responseObject); 
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) { 
     //failure :(
     completionBlock([NSDictionary dictionaryWithObject:[error localizedDescription] forKey:@"error"]); 
    }]; 

    [operation start]; 
} 

@end 

的index.php

<? 
session_start(); 

require("lib.php"); 

header("Content-Type:application/json"); 

switch ($_POST['command']) 
{ 
    case "login": 
     login($_POST['username'],$_POST['password']); 
     break; 
    case "register"; 
     register($_POST['username'],$_POST['password']); 
     break; 
} 

lib.php

<?php 
$link = mysqli_connect("localhost","root","root"); 
mysqli_select_db($link,"test"); 

header("Content-Type:application/json"); 

function errorJson($msg){ 
    print json_encode(array('error'=>$msg)); 
    exit(); 
} 

function register($user, $pass) { 

    //check if username exists in the database (inside the "users" table) 
    $login = query("SELECT username FROM users WHERE username='%s' limit 1", $user); 

    if (count($login['result'])>0) { 

     //the username exists, return error to the iPhone app 
     errorJson('Username already exists'); 
    } 

    //try to insert a new row in the "users" table with the given username and password 
    $result = query("INSERT INTO users(username, password) VALUES('%s','%s')", $user, $pass); 

    if (!$result['error']) { 
     //registration is susccessfull, try to also directly login the new user 
     login($user, $pass); 
    } else { 
     //for some database reason the registration is unsuccessfull 
     errorJson('Registration failed'); 
    } 

} 

CDRegisterViewController.m

- (IBAction)signUp:(id)sender 
{ 
    // form fields validation 
    if (self.usernameField.text.length < 4 || self.passwordField.text.length < 4){ 
     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Your password is too short" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil]; 
     [alertView show]; 
    } 

    // salt the password 
    NSString *saltedPassword = [NSString stringWithFormat:@"%@%@", self.passwordField.text, kSalt]; 

    // prepare hashed storage 
    NSString *hashedPassword = nil; 
    unsigned char hashedPasswordData[CC_SHA1_DIGEST_LENGTH]; 

    //hash the pass 
    NSData *data = [saltedPassword dataUsingEncoding:NSUTF8StringEncoding]; 
    if (CC_SHA1([data bytes], [data length], hashedPasswordData)) { 
     hashedPassword = [[NSString alloc] initWithBytes:hashedPasswordData length:sizeof(hashedPasswordData) encoding:NSASCIIStringEncoding]; 
    } else { 
     UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Password couldn't be sent" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil]; 
     [alertView show]; 
     return; 
    } 

    // set the parameters to post 
    NSString *command = @"register"; 
    NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:command, @"command", 
            self.usernameField.text, @"username", hashedPassword, @"password", nil]; 

    // make the call to the api 
    [[API sharedInstance] commandWithParams:params onCompletion:^(NSDictionary *json) 
    { 
     //result returned 
     NSDictionary* res = [[json objectForKey:@"result"] objectAtIndex:0]; 

     if ([json objectForKey:@"error"]==nil && [[res objectForKey:@"IdUser"] intValue]>0) { 
      //success 
      [[API sharedInstance] setUser: res]; 
      [self.presentingViewController dismissViewControllerAnimated:YES completion:nil]; 

      //show message to the user 
      [[[UIAlertView alloc] initWithTitle:@"Logged in" 
             message:[NSString stringWithFormat:@"Welcome %@",[res objectForKey:@"username"] ] 
             delegate:nil 
           cancelButtonTitle:@"Close" 
           otherButtonTitles: nil] show]; 

     } else { 
      //error 
      UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error" message:[json objectForKey:@"error"] delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:nil, nil]; 
      [alertView show]; 
     } 
    }]; 
} 
+0

你的「醃」真的不是因爲每個密碼都使用相同的鹽(kSalt)。 – zaph

+0

@Zaph我跑了查爾斯,這是說它發佈了命令「註冊」,以及用戶名/密碼。當我轉到「響應」選項卡時,它給了我index.php的來源。它是否正確? – jsmos

+0

我在?>標記之間有一個空格,它現在註冊。謝謝 :) – jsmos

回答

0

你有沒有看從服務中的數據/與分析,如查爾斯代理?這將是第一步 - 找出問題出在服務器還是iOS上。接下來提供一些數據,請求和響應。找到不正確並修復的結尾。

相關問題