You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CodeIgniter同控制器内加载视图并传递数据的实现问题

解决CodeIgniter Ajax登录后加载视图并传递数据的问题

你遇到的核心问题是Ajax异步请求的处理逻辑不对:当你用Ajax提交表单时,控制器直接加载视图的内容会返回给Ajax的响应对象,而不是自动替换当前页面。另外你还漏了把数据传递给视图,同时SQL语句存在注入风险,我们一步步来修复:

1. 修复控制器的validate_LogIn方法

首先,你需要修改控制器逻辑,这里提供两种常用方案:

方案一:返回视图HTML,用JS替换页面内容

修改控制器,把视图渲染后的HTML返回给Ajax,同时传递用户数据:

<?php
class logInCon extends CI_Controller {
    public function login() {
        $this->load->view("Login");
    }

    public function validate_LogIn() {
        $uname = $this->input->post('uname');
        $pass = $this->input->post('pass');
        
        $this->load->model("accsModel");
        $data = $this->accsModel->logInCheck($uname, $pass);
        $check = $data['verified'];

        if ($check <= 0) {
            echo json_encode(['status' => 'error', 'message' => "Not a valid member"]);
        } else {
            // 获取用户数据并传递给视图
            $data['logged'] = $this->accsModel->getUser($uname, $pass);
            // 第三个参数设为true,返回视图的HTML字符串而不是直接输出
            $html = $this->load->view('comms', $data, true);
            echo json_encode(['status' => 'success', 'html' => $html]);
        }
    }
}
?>

方案二:返回重定向地址,让页面跳转

如果更倾向于传统的页面跳转模式,可以把用户信息存入Session,然后让前端跳转到新页面加载视图:

<?php
class logInCon extends CI_Controller {
    public function login() {
        $this->load->view("Login");
    }

    public function validate_LogIn() {
        $uname = $this->input->post('uname');
        $pass = $this->input->post('pass');
        
        $this->load->model("accsModel");
        $data = $this->accsModel->logInCheck($uname, $pass);
        $check = $data['verified'];

        if ($check <= 0) {
            echo json_encode(['status' => 'error', 'message' => "Not a valid member"]);
        } else {
            // 将用户信息存入Session,方便后续页面调用
            $user_data = $this->accsModel->getUser($uname, $pass);
            $this->session->set_userdata('logged_user', $user_data);
            echo json_encode(['status' => 'success', 'redirect_url' => base_url('logInCon/comms')]);
        }
    }

    // 新增加载comms视图的独立方法
    public function comms() {
        $data['logged'] = $this->session->userdata('logged_user');
        $this->load->view('comms', $data);
    }
}
?>

2. 修复Model的SQL注入风险

你的getUser方法直接将用户输入拼进SQL,存在严重的注入漏洞,改成CodeIgniter的查询绑定方式:

<?php
class accsModel extends CI_Model {
    public function getBps() {
        $query = $this->db->get('bps');
        return $query->result();
    }

    public function getUser($uname, $psswrd) {
        // 使用?作为占位符,通过数组传递参数,自动防止SQL注入
        $sql = "SELECT `bps`.*, `users`.bps_id 
                FROM `bps` 
                LEFT JOIN `users` ON `bps`.id = `users`.bps_id 
                AND `users`.`uname` = ? 
                AND `users`.`pwd` = ? 
                WHERE `users`.bps_id != '' OR `users`.bps_id IS NOT NULL";
        $query = $this->db->query($sql, [$uname, $psswrd]);
        return $query->result();
    }

    public function logInCheck($uname, $psswrd) {
        $this->db->select('COUNT(*) AS verified');
        $this->db->where('uname', $uname);
        $this->db->where('pwd', $psswrd);
        $this->db->limit(1);
        return $this->db->get('users')->row_array();
    }
}
?>

3. 修复前端Ajax的响应处理逻辑

根据上面的控制器方案,修改前端JS代码:

对应方案一的JS修改

<body>
    <div class="container">
        <div class="row">
            <div class="LogForm">
                <div class="col-md-12">
                    <input type="text" id="bpCode" name="bpCode">
                </div>
                <div class="col-md-12">
                    <input type="password" id="pass" name="pass">
                </div>
                <div class="btn">
                    <span id="emptyF" hidden style="color:red;"></span>
                    <button id="submit" class="btn btn-info btn-lg btn-block">Login</button>
                    <span id="result"></span>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#submit").click(function(e) {
                e.preventDefault(); // 阻止按钮默认提交行为
                var uname = $('#bpCode').val();
                var pass = $('#pass').val();

                if(uname == "" || pass =="") {
                    $("#emptyF").attr("hidden", false).html("Please fill in the form");
                } else {
                    $("#emptyF").attr("hidden", true);
                    $.ajax({
                        type: "POST",
                        url: "<?php echo base_url('logInCon/validate_LogIn'); ?>",
                        data: { uname : uname, pass : pass },
                        dataType: 'json', // 指定接收JSON格式响应
                        success: function(response) {
                            if(response.status === 'error') {
                                $("#result").html(response.message).css('color', 'red');
                            } else {
                                // 替换整个页面内容为新视图的HTML
                                $('body').html(response.html);
                            }
                        }
                    });
                }
            });
        });
    </script>
</body>

对应方案二的JS修改

<body>
    <div class="container">
        <div class="row">
            <div class="LogForm">
                <div class="col-md-12">
                    <input type="text" id="bpCode" name="bpCode">
                </div>
                <div class="col-md-12">
                    <input type="password" id="pass" name="pass">
                </div>
                <div class="btn">
                    <span id="emptyF" hidden style="color:red;"></span>
                    <button id="submit" class="btn btn-info btn-lg btn-block">Login</button>
                    <span id="result"></span>
                </div>
            </div>
        </div>
    </div>
    <script type="text/javascript">
        $(document).ready(function() {
            $("#submit").click(function(e) {
                e.preventDefault(); // 阻止按钮默认提交行为
                var uname = $('#bpCode').val();
                var pass = $('#pass').val();

                if(uname == "" || pass =="") {
                    $("#emptyF").attr("hidden", false).html("Please fill in the form");
                } else {
                    $("#emptyF").attr("hidden", true);
                    $.ajax({
                        type: "POST",
                        url: "<?php echo base_url('logInCon/validate_LogIn'); ?>",
                        data: { uname : uname, pass : pass },
                        dataType: 'json',
                        success: function(response) {
                            if(response.status === 'error') {
                                $("#result").html(response.message).css('color', 'red');
                            } else {
                                // 跳转到指定页面加载视图
                                window.location.href = response.redirect_url;
                            }
                        }
                    });
                }
            });
        });
    </script>
</body>

4. 补充注意事项

  • 如果使用方案二,需要确保已经加载了Session库:在config/autoload.php中添加$autoload['libraries'] = array('session');
  • CodeIgniter加载视图时不需要加.php后缀,所以$this->load->view('comms')即可,不用写comms.php
  • 重要提醒:当前代码明文存储密码非常不安全,建议使用CodeIgniter的password_hash()加密密码,登录时用password_verify()验证

内容的提问来源于stack exchange,提问作者Edhans

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.12 04:51:40