Ошибка — Ожидаемый тип содержимого текст / json получил текст / html

#php #ios #json

#php #iOS #json

Вопрос:

После попытки Register функции в этом приложении, он показывает ошибку через UIAlert , который говорит

Ошибка

Ожидаемый тип содержимого {[«текст / json», «приложение / json», «текст / javascript» )}, получил текст / html.

Как можно исправить этот тип ошибки? После просмотра вкладки обзор в Charles Proxy он подтверждает, что Content-Type есть text/html; charset=UTF-8 . Charles proxy также показывает username password ввод и, но, похоже, он не выполняется.

Это заголовок, используемый в приложении

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

Что вызывает эту ошибку и как ее можно решить?

 //the web location of the service
#define kAPIHost @"http://192.168.1.3:8888"
#define kAPIPath @"iReporter/"
  

Редактировать

Предполагается, что приложение регистрирует пользователя в базе данных mysql, используя AFNetworking in iOS и Json в соответствующем php web service

lib.php (помогает подключиться к базе данных mysql)

 <?

//setup db connection
$link = mysqli_connect("localhost","root","root");
mysqli_select_db($link, "iReport");

//executes a given sql query with the params and returns an array as result
function query() {
global $link;
$debug = false;

//get the sql query
$args = func_get_args();
$sql = array_shift($args);

//secure the input
for ($i=0;$i<count($args);$i  ) {
    $args[$i] = urldecode($args[$i]);
    $args[$i] = mysqli_real_escape_string($link, $args[$i]);
}

//build the final query
$sql = vsprintf($sql, $args);

if ($debug) print $sql;

//execute and fetch the results
$result = mysqli_query($link, $sql);
if (mysqli_errno($link)==0 amp;amp; $result) {

    $rows = array();

    if ($result!==true)
    while ($d = mysqli_fetch_assoc($result)) {
        array_push($rows,$d);
    }

    //return json
    return array('result'=>$rows);

} else {

    //error
    return array('error'=>'Database error');
}
}

//loads up the source image, resizes it and saves with -thumb in the file name
function thumb($srcFile, $sideInPx) {

$image = imagecreatefromjpeg($srcFile);
$width = imagesx($image);
$height = imagesy($image);

$thumb = imagecreatetruecolor($sideInPx, $sideInPx);imagecopyresized($thumb,$image,0,0,0,0,$sideInPx,$sideInPx,$width,$height);

imagejpeg($thumb, str_replace(".jpg","-thumb.jpg",$srcFile), 85);

imagedestroy($thumb);
imagedestroy($image);
}

?>
  

Index.php (файл, к которому подключается приложение для вызова команд php через ответ AFNetworking Json)

 <?
/* iReporter complete web demo project
 *
 * index.php takes care to check the "command" request
 * and call the proper API function to process the user request
 * 
 */

// this line starts the server session - that means the server will "remember" the user
// between different API calls - ie. once the user is authorized, he will stay logged in for a while
 session_start();

 // the require lines include the lib and api source files
require("lib.php");
require("api.php");

// this instructs the client (in this case the iPhone app) 
// that the server will output JSON data
header("Content-Type: application/json");

// the iPhone app sends over what "command" of the API it wants executed
// the tutorial covers "login","register","upload", "logout" and "stream"
// so using a switch statement for this taks makes most sense

// the functions you call inside the switch are found in the api.php file
switch ($_POST['command']) {
case "login":
    login($_POST['username'], $_POST['password']); 
    break;

case "register":
    register($_POST['username'], $_POST['password']); 
    break;
  

api.php (файл index.php подключается для вызова функций сервера, используемых в приложении, таких как вход в систему и регистрация)

 <?

// helper function, which outputs error messages in JSON format
// so that the iPhone app can read them
// the function just takes in a dictionary with one key "error" and 
// encodes it in JSON, then prints it out and then exits the program
function errorJson($msg){
print json_encode(array('error'=>$msg));
exit();
}

// register API
function register($user, $pass) {

//check if username exists in the database (inside the "login" table)
$login = query("SELECT username FROM login 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 "login" table with the given username and password
$result = query("INSERT INTO login(username, pass) VALUES('%s','%s')", $user, $pass);

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

}

//login API
function login($user, $pass) {

// try to match a row in the "login" table for the given username and password
$result = query("SELECT IdUser, username FROM login WHERE username='%s' AND pass='%s' limit 1", $user, $pass);

if (count($result['result'])>0) {
    // a row was found in the database for username/pass combination
    // save a simple flag in the user session, so the server remembers that the user is authorized
    $_SESSION['IdUser'] = $result['result'][0]['IdUser'];

    // print out the JSON of the user data to the iPhone app; it looks like this:
    // {IdUser:1, username: "Name"}
    print json_encode($result);
} else {
    // no matching username/password was found in the login table
    errorJson('Authorization failed');
}

}

//upload API
function upload($id, $photoData, $title) {

// index.php passes as first parameter to this function $_SESSION['IdUser']
// $_SESSION['IdUser'] should contain the user id, if the user has already been authorized
// remember? you store the user id there in the login function
if (!$id) errorJson('Authorization required');

// check if there was no error during the file upload
if ($photoData['error']==0) {

    // insert the details about the photo to the "photos" table
    $result = query("INSERT INTO photos(IdUser,title) VALUES('%d','%s')", $id, $title);
    if (!$result['error']) {

        // fetch the active connection to the database (it's initialized automatically in lib.php)
        global $link;

        // get the last automatically generated ID in the photos table
        $IdPhoto = mysqli_insert_id($link);

        // move the temporarily stored file to a convenient location
        // your photo is automatically saved by PHP in a temp folder
        // you need to move it over yourself to your own "upload" folder
        if (move_uploaded_file($photoData['tmp_name'], "upload/".$IdPhoto.".jpg")) {

            // file moved, all good, generate thumbnail
            thumb("upload/".$IdPhoto.".jpg", 180);

            //just print out confirmation to the iPhone app
            print json_encode(array('successful'=>1));
        } else {
            //print out an error message to the iPhone app
            errorJson('Upload on server problem');
        };

    } else {
        errorJson('Upload database problem.'.$result['error']);
    }
} else {
    errorJson('Upload malfunction');
}
}

//logout API
function logout() {

// by saving an empty array to $_SESSION you are
// effectively destroying all the user session data
// ie. the server won't "remember" anymore anything about
// the current user
$_SESSION = array();

// and to make double-sure, there's also a built-in function 
// which wipes out the user session
session_destroy();
}

//stream API
//
// there are 2 ways to use the function:
// 1) don't pass any parameters - then the function will fetch all photos from the database
// 2) pass a photo id as a parameter - then the function will fetch the data of the requested photo
//
// Q: what "$IdPhoto=0" means? A: It's the PHP way to say "first param of the function is $IdPhoto, 
// if there's no param sent to the function - initialize $IdPhoto with a default value of 0"
function stream($IdPhoto=0) {

 if ($IdPhoto==0) {

    // load the last 50 photos from the "photos" table, also join the "login" so that you can fetch the 
    // usernames of the photos' authors
    $result = query("SELECT IdPhoto, title, l.IdUser, username FROM photos p JOIN login l ON (l.IdUser = p.IdUser) ORDER BY IdPhoto DESC LIMIT 50");

} else {
    //do the same as above, but just for the photo with the given id
    $result = query("SELECT IdPhoto, title, l.IdUser, username FROM photos p JOIN login l ON (l.IdUser = p.IdUser) WHERE p.IdPhoto='%d' LIMIT 1", $IdPhoto);
}

if (!$result['error']) {
    // if no error occured, print out the JSON data of the 
    // fetched photo data
    print json_encode($result);
} else {
    //there was an error, print out to the iPhone app
    errorJson('Photo stream is broken');
}
}
?>
  

Редактировать: ошибка отображается при попытке зарегистрировать функцию на экране входа в приложения

Комментарии:

1. Пожалуйста, добавьте весь соответствующий код в сам вопрос, а не в виде ссылок за пределами сайта. Вы также должны более подробно объяснить, что делает ваш код. Когда вы получаете это сообщение? В PHP? Когда ваше приложение отправляет ответ или когда оно делает запрос? На данный момент это очень неясно.

2. Из-за ошибки кажется, что сервер не возвращает ответ json, как ожидало приложение. Проверьте код api и убедитесь, что ваш api возвращает ответ json в сценариях успеха и ошибок

3. Я не эксперт в php, но я думаю, что вы должны использовать echo json_encode($result); или echo errorJson() в соответствующих случаях.

4. Вы должны использовать параметризованные подготовленные операторы вместо того, чтобы вручную экранировать и строить свои запросы подобным образом.

5.Никогда не храните пароли в виде открытого текста! Предупреждение: храните только хэши паролей. Используйте PHP password_hash() и password_verify() . Если вы используете версию PHP ниже 5.5 (на что я очень надеюсь, что это не так), вы можете использовать библиотеку password_compat, чтобы получить ту же функциональность.