PHP中通过AJAX设置Cookie并运行Session的问题排查
你遇到的核心问题是**loginUser.php中没有启动Session**,导致设置的$_SESSION['userName']根本没有被保存下来。另外你的代码还有几个安全和逻辑上的问题,我一起帮你梳理修复:
1. 核心问题:Session未启动
你的main_modal.php里虽然有session_start(),但loginUser.php是通过AJAX独立请求的,它并没有包含main_modal.php,也没有自己调用session_start()。Session必须在任何输出之前启动,所以在loginUser.php的最顶部必须添加session_start(),或者包含你的main_modal.php(如果它确实在顶部有session_start()的话)。
修复后的loginUser.php开头:
<?php session_start(); // 必须添加这行,或者 include("includes/main_modal.php"); $q = $_GET["q"]; $p = $_GET["p"]; // ... 后续代码
2. 严重安全问题:SQL注入
你直接把用户输入的$q和$p拼进SQL语句,这是极高的SQL注入风险,攻击者可以轻易篡改你的SQL查询,甚至获取整个数据库的数据。必须使用MySQLi预处理语句来避免这个问题:
修改loginUser.php中的数据库查询部分:
// 替换原来的查询代码 $dbc = mysqli_connect("localhost", "lucy", "abc123", "userDB"); if(mysqli_connect_error()) { echo "Database cannot be connected", mysqli_connect_error(); exit(); } // 使用预处理语句 $query = "SELECT * FROM users WHERE userEmail = ? AND userPassword = SHA(?)"; $stmt = mysqli_prepare($dbc, $query); mysqli_stmt_bind_param($stmt, "ss", $q, $p); // "ss"表示两个字符串参数 mysqli_stmt_execute($stmt); $result = mysqli_stmt_get_result($stmt); $num = mysqli_num_rows($result); if($num != 0) { $row = mysqli_fetch_array($result, MYSQLI_ASSOC); $_SESSION['userName'] = $row['userEmail']; $name = $row['userEmail']; setcookie("dbMember", $name, time() + 60*60*2, "/"); // 有效期2小时 echo "true"; } else { echo "Username or Password is incorrect. Please try again."; } // 记得关闭语句和连接 mysqli_stmt_close($stmt); mysqli_close($dbc);
3. 密码传输不安全:改用POST请求
你现在用GET请求传递密码,密码会明文出现在URL里,还会被记录在服务器日志中,非常不安全。应该改用POST请求:
修改前端AJAX代码:
// 替换原来的xmlhttp.open和send部分 xmlhttp.open("POST", "loginUser.php", true); // 设置请求头,告诉服务器我们发送的是表单数据 xmlhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); // 用POST方式发送数据,对参数编码避免特殊字符问题 xmlhttp.send("q=" + encodeURIComponent(strUser) + "&p=" + encodeURIComponent(strPsswrd));
修改loginUser.php获取参数的方式:
// 替换原来的$q和$p获取代码 $q = $_POST["q"]; $p = $_POST["p"];
4. 优化:Session和Cookie的检查逻辑
index.php里同时检查$_SESSION和$_COOKIE其实没必要,因为Session本身依赖Cookie(默认情况下),只要Session正常工作,直接检查$_SESSION['userName']就足够了:
<?php include("includes/main_modal.php"); // 这里已经有session_start() ?> <?php if(isset($_SESSION['userName'])) { $user = $_SESSION['userName']; echo $user; } else { echo "goback"; } ?>
总结
按上面的步骤修复后,Session就能正常工作了,同时也解决了代码中的安全隐患。核心就是确保在所有需要使用Session的PHP文件中都启动了Session,无论是直接访问的页面还是AJAX请求的接口。
内容的提问来源于stack exchange,提问作者Lucy Hong

