服务器在ajax调用上返回空响应可能是路由错误


Server returning empty response on ajax call probably routing error

我有一个简单的搜索输入,我想在点击时使用jquery on blur通过ajax调用来POST数据。ajax调用是以下代码:

$(".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);
                         }
});
        });

当进行post调用时,我得到一个重定向(找到302)到我的自定义404页面。但是,当我签入chrome的控制台时,adminController.php的位置是正确的。如果我手动删除重定向条件,我会得到200 ok的服务器响应,但响应为空。在我的adminController.php中,我有以下代码(构造函数中返回后的代码在这里不是真正必要的):`

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

    }
}`

我想实现的是,不要有提交按钮,只需将所有内容发布在blur上,并将结果转储到#searchResultsdiv上。我认为问题与我的路由器类有关。在发布请求的第一个位置重定向似乎不健康,所以我将粘贴路由器和引导程序文件的代码。

bootstrap.hp:

    <?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();

和router.php

类路由器{

private $routes = array();
private $method = array();
public function __construct(){}
public function __destruct(){}

/***将可用路由及其方法(字符串、匿名函数等)添加到数组中*/

    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();
        }
    }
}

最后但同样重要的是,我的.htaccess

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

编辑1:我使用的是Xampp,我的域是localhost/Costing/。我尝试将url更改为Costing/admin,这样我就摆脱了重定向。但是,除非我删除dataType="json",否则我会得到空响应(如果我删除json,我会得到带有脚本的完整html页面,也就是adminView文件)。使用MVC架构

编辑2:我找到了解决办法。看起来我是对的,而路由是问题的根源。因此,我创建了一个ajaxHandler.php文件,并将其放在Costing目录之外,并编辑了如下ajax url:"http://localhost/ajaxHandler.php"。我从该文件中得到了有效的响应,但我无法真正处理根目录之外的文件。所以我需要更改htaccess。任何想法都欢迎

我自己找到了解决方案,问题出在htaccess上。基本上线路

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

不允许我的url请求文件或目录,所以任何以.php结尾的内容都是被禁止的。我必须创建一个文件夹,并将我的ajax处理文件放在那里,然后添加一个异常,如下所示:

ReWriteRule ^ajax/ - [L,NC]

现在htaccess允许调用这个文件,我可以正确使用它。虽然我不确定这是否安全,但我仍然不知道为什么url Costing/admin没有像玛丽安正确指出的那样工作。如果有人发现为什么会很棒

除了bootstrap.php之外,我没有看到任何实际执行的php代码(即index.php)。

对于单个服务器端入口点,正如您正在努力的那样,您将希望所有请求最终都在入口点上,并且完整的路由请求完好无损。从这个入口点,您可以调用路由器,然后路由器将调用adminController类。

操作顺序变为:

  1. Ajax请求发送到/admin
  2. 请求被定向到index.php
  3. Index.php启动引导程序以加载自动加载器
  4. Index.php使用传入路径调用路由器
  5. 路由器调用实际的AdminController类

空响应可能是因为服务器只执行adminController.php,而adminControllerphp似乎没有回显任何内容(类从未在该文件中初始化)。