The server returns the empty answer on the ajax call probably the routing error

advertisements

I have a simple search input that i want to POST data with an ajax call on click out using jquery on blur. The ajax call is the following code:

$(".ajax").blur(function(){

            $.ajax({

                     type: "POST",
                     url : "adminController.php",
                     data : {
                     searchInput: $(this).val()
                     },
                     dataType : "json",
                     context : $("#searchResults"),

                    success: function(data)
                         {
                            $(this).text(data);
                            alert(data);
                         },
                    error: function (xhr,textStatus,err)
                         {
                            console.log("readyState: " + xhr.readyState);
                            console.log("responseText: "+ xhr.responseText);
                            console.log("status: " + xhr.status);
                            console.log("text status: " + textStatus);
                            console.log("error: " + err);
                         }
});
        });

When the post call is made, i get a redirect (302 found) to my custom 404 page. However, the adminController.php is located correctly when i checked in chrome's console. If I remove the redirecting condition manually I get a 200 ok server response but with empty response. In my adminController.php I have the following code(code after the return in the constructor is not really necessary here): `

    class adminController
    {
        private $postData;
        private $errorMessage;
        public function __construct()
        {
        $this->postData=array();
        $this->errorMessage='';
        session_start();
        if(sessionClass::get('Username')== false || loginModel::checkAdmin()== false)
        {
            header('Location: /Costing/login');
            exit();
        }

        if(($_POST)) {
            //$this->handlePostData(); I entered the following
 simple code to make sure my json return array is not the issue for my problems
            $cars=array("Volvo","BMW","Toyota");
            return json_encode($cars);
        }

    }
    public function __destruct(){ }

    public function displayPage()
    {
        $admin = new adminModel();
        $nonAdminUsers = $admin->databaseInteract(sqlQueries::getNonAdmin());

        $adminView = new adminView();
        $adminView = $adminView->createAdminPage($nonAdminUsers);

        echo $adminView;

    }

    private function handlePostData()
    {

        foreach($_POST as $key => $value)
        {
            if(!empty($value)) {
                $sanitized_value = filter_var($value,FILTER_SANITIZE_FULL_SPECIAL_CHARS);
                $sanitized_value = filter_var($sanitized_value,FILTER_SANITIZE_STRING);
                $sanitized_value = filter_var($sanitized_value,FILTER_SANITIZE_MAGIC_QUOTES);
                $this->postData[$key] = $sanitized_value;

            }
            else
                $this->errorMessage.= $key.' is empty.';
        }
        if(!empty($this->postData))
        {
            $admin = new adminModel();
            foreach ($this->postData as $key => $value)
            {
                if($key == 'Seller' || $key == 'Customer' || $key == 'Product')
                {
                    $adminQuery = sqlQueries::searchOrders();
                    $tempArray['field']=$key;
                    $tempArray['value']=$value;

                    $result = $admin->databaseInteract($adminQuery,$tempArray);
                    $adminView = new adminView($result);
                }
                else if($key == 'nonAdmins')
                {
                    $adminQuery = sqlQueries::promoteToAdmin();
                    $tempArray['Username']=$value;
                    $result = $admin->databaseInteract($adminQuery,$tempArray);
                    $adminView = new adminView();
                    $adminView->displayErrors($result);

                }
                else
                {
                    $tempArray['value']=$value;
                    $adminQuery = sqlQueries::setConstants($key);
                    $result = $admin->databaseInteract($adminQuery, $tempArray);
                    $adminView = new adminView();
                    $adminView->displayErrors($result);

                }
            }
        }

    }
}`

what I am trying to achieve is instead of having a submit button, just post everything on blur and dump the results on the #searchResults div. I think the problem has to do with my router class. The redirect in the first place on a post request did not seem healthy, so I will paste the code of my router and bootstrap files.

bootstrap.php:

    <?php

/**
 * @param $className
 * bootstrap file for autoload function and router calling
 *
 */

function my_autoloader($class) {

    if (file_exists(realpath(__DIR__). DIRECTORY_SEPARATOR . $class . '.php'))
    include realpath(__DIR__). DIRECTORY_SEPARATOR . $class . '.php';
    else if (file_exists(realpath(__DIR__). '\\Classes\\' . $class . '.php'))
    include realpath(__DIR__). '\\Classes\\' . $class . '.php';
    else if (file_exists(realpath(__DIR__). '\\Classes\\Controller\\' . $class. '.php'))
    include realpath(__DIR__). '\\Classes\\Controller\\' . $class. '.php';
    else if (file_exists(realpath(__DIR__). '\\Classes\\Model\\' . $class. '.php'))
    include realpath(__DIR__). '\\Classes\\Model\\' . $class. '.php';
    else if (file_exists(realpath(__DIR__). '\\Classes\\View\\' . $class. '.php'))
    include realpath(__DIR__). '\\Classes\\View\\' . $class. '.php';

    else
    {
       $error = new errorController('classNotFound');
    }
}

spl_autoload_register('my_autoloader');

    $routes = new router();
    $routes->add('/home', 'homeController');
    $routes->add('/login', 'loginController');
    $routes->add('/register', 'registerController');
    $routes->add('/index.php', 'homeController');
    $routes->add('/invoicing','invoiceController');
    $routes->add('/admin','adminController');
    $routes->add('/404','errorController');
    $routes->submit();

and router.php

class router {

private $routes = array();
private $method = array();

public function __construct(){}

public function __destruct(){}

/** * Adds available routes to an array with their methods (strings, anonymous functions, etc.) */

    public function add($uri, $method = null)
        {

        $this->routes[] =trim($uri,'/');
        if ($method!= null)
            $this->method[]= $method;
        else
            throw new exception();

    }

    /**
     * Matches routes to controller actions.
     */
    public function submit()
    {
        $count=0;

        if(isset($_GET['uri'])) {
            $uri = $_GET['uri'];
        }
        else
            $uri = '/home';

        foreach( $this->routes as $key => $value)
        {

            if (preg_match("#^$value$#", $uri))
            {

                if (is_string($this->method[$key]))
                {
                    $userMethod = $this->method[$key];
                    $display = new $userMethod();
                    $display->displayPage();
                }
                else call_user_func($this->method[$key]);
            }
            else $count++;

        }

        if($count == sizeof($this->routes))
        {
            header ('Location: /Costing/404');
            exit();
        }

    }
}

last but not least, my .htaccess

ReWriteEngine On
ReWriteRule ^public/ - [L,NC]
ReWriteBase /Costing/
RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d
RewriteRule ^(.+)$ index.php?uri=$1 [QSA,L]

Edit 1: I'm using Xampp and my domain is localhost/Costing/. I tried changing the url to Costing/admin so i got rid of the redirect. But still, unless I remove the dataType = "json" I get empty response back (if i remove json i get back the full html page with the scripts, aka adminView file). Using MVC architecture

Edit 2: I found a way around. Seems like i was right and the routing is causing the issue. So I created an ajaxHandler.php file and placed it outside the Costing directory and edited the ajax url like this: "http:// localhost/ajaxHandler.php". I get a valid response from this file but I can't really work with a file outside the root directory. So I need to change the htaccess. Any ideas are welcome


I found the solution myself, the problem was on htaccess. Basically the lines

RewriteCond %(REQUEST_FILENAME) !-f
RewriteCond %(REQUEST_FILENAME) !-d

Did not allow my urls to ask for files or directories, so anything ending on .php was forbidden. I had to create a folder and place my ajax handling file in there and add an exception like so:

ReWriteRule ^ajax/ - [L,NC]

Now the htaccess allows calls to this file and I can use it properly. I'm not sure this is secure though and I still have no idea why the url Costing/admin didn't work as marian correctly noted. If anyone finds out why it would be great