简体   繁体   中英

AJAX always thinks php returns are successful even after failure

I have a php script that adds a new user account. Part of the addAccount() checks if the username is valid and if not, returns an exception that it's not available (fatal error shows up). My issue is that the AJAX interprets everything as a success and displays the success message no matter what. How do I fix this or at least catch the fatal error and display the proper message?

$(document).on('click', '#createUserBtn', function(e){
    e.preventDefault();
    $.ajax({
        url:'addUser.php',
        type:'post',
        data:$('#addUser').serialize(),
        success:function(){

                toastr.success("User successfully added!");
            },
        error: function(){
            toastr.warning('Uh-oh! Something went wrong with adding this user!');
        }
    });
});

addUser.php

<?php
session_start();
/* Include the database connection file (remember to change the connection parameters) */
require './db_inc.php';

/* Include the Account class file */
require './account_class.php';

  $type = $_POST['type'];
  $username = $_POST['uname'];
  $password = $_POST['password'];
  $comp = $_POST['company'];
  $email = $_POST['email'];
  $fname = $_POST['fname'];
  $lname = $_POST['lname'];
  $query = $pdo->query("SELECT * FROM accounts WHERE email ='".$email."'");

$account = new Account();
// Will print all the values received.
    $newId = $account->addAccount($username, $password, $comp, $email, $fname, $lname, $type);
    header('Location: ./dashboard.php?user='.$username);



?>

Here is the addAccount function that is used...

    public function addAccount(string $name, string $passwd, string $comp, string $email, string $fname, string $lname, string $type): int
    {
        /* Global $pdo object */
        global $pdo;

        /* Trim the strings to remove extra spaces */
        $name = trim($name);
        $passwd = trim($passwd);

        /* Check if the user name is valid. If not, throw an exception */
        if (!$this->isNameValid($name))
        {
            throw new Exception('Invalid user name');
        }

        /* Check if the password is valid. If not, throw an exception */
        if (!$this->isPasswdValid($passwd))
        {
            throw new Exception('Invalid password');
        }

        /* Check if an account having the same name already exists. If it does, throw an exception */
        if (!is_null($this->getIdFromName($name)))
        {
            throw new Exception('User name not available');
        }

        /* Finally, add the new account */

        /* Insert query template */
        $query = 'INSERT INTO login.accounts (account_name, account_passwd, fname, lname, company, email, user_type) VALUES (:name, :passwd, :fname, :lname, :comp, :email, :type)';

        /* Password hash */
        $hash = password_hash($passwd, PASSWORD_DEFAULT);

        /* Values array for PDO */
        $values = array(':name' => $name, ':passwd' => $hash, ':lname' => $lname, ':fname' => $fname, ':comp' => $comp, ':email' => $email, ':type' => $type);

        /* Execute the query */

            $res = $pdo->prepare($query);
            $res->execute($values);

        /* Insert query template */





        /* Return the new ID */
        return $pdo->lastInsertId();
    }

You can use http_response_code() to return a HTTP error code (usually code 500 : internal server error).

You can do that with a try/catch block :

try
{
     ...
     $account = new Account();
     // Will print all the values received.
     $newId = $account->addAccount($username, $password, $comp, $email, $fname, $lname, $type);
     header('Location: ./dashboard.php?user='.$username);
}
catch(Exception $e)
{
    http_response_code(500);
    exit();
}

First you can't redirect user via php if you request something from javascript, remove this line from addUser.php

header('Location: ./dashboard.php?user='.$username);

Now to return result from php to client you must DIE php with value, the best way is JSON

In addUser.php check what you want and return the value like this:

    <?php

session_start();
/* Include the database connection file (remember to change the connection parameters) */
require './db_inc.php';

/* Include the Account class file */
require './account_class.php';

  $type = $_POST['type'];
  $username = $_POST['uname'];
  $password = $_POST['password'];
  $comp = $_POST['company'];
  $email = $_POST['email'];
  $fname = $_POST['fname'];
  $lname = $_POST['lname'];
  $query = $pdo->query("SELECT * FROM accounts WHERE email ='".$email."'");

$account = new Account();
// Will print all the values received.
    $newId = $account->addAccount($username, $password, $comp, $email, $fname, $lname, $type);
        if(intval($newId) > 0) // if user created
            die(json_encode(array('status' => 'ok')));
        else
            die(json_encode(array('status' => 'error')));
    ?>

Then change your clientSide like below:

$(document).on('click', '#createUserBtn', function(e){
    e.preventDefault();
    $.ajax({
        url:'addUser.php',
        type:'post',
        data:$('#addUser').serialize(),
        dataType: "json", // <- Add this line
        success:function(response){ // <- add response parameter
                //Here check result
                if(response['status'] == 'ok')
                    toastr.success("User successfully added!");
                else
                    toastr.warning('Uh-oh! Something went wrong with adding this user!');

            },
        error: function(){

        },
    statusCode: { // <- Add this property
        500: function() {
             toastr.warning('Uh-oh! Something went wrong with adding this user!');
        }
    }
    });
});

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM