预期的内容类型text / json得到text / html

时间:2014-02-12 20:53:29

标签: php ios json afnetworking

我正在开发一个Web服务,正在编写注册/登录API。当我尝试在iOS模拟器中注册时,我得到“预期的内容类型text / json got text / html”。我现在花了几个小时试图调试并找到问题,但我没看到为什么我没有得到JSON数据。

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];
        }
    }];
}

1 个答案:

答案 0 :(得分:4)

您是否使用Charles Proxy等分析器查看了服务中的数据?这将是第一步 - 弄清楚问题是在服务器还是iOS上。接下来提供一些数据,请求和响应。找到不正确的结尾并修复。