登录功能代码无法保存并显示Cookie的问题排查求助
我用JavaScript开发了登录页面,前端代码如下:
<script src="https://code.jquery.com/jquery-3.6.0.min.js"> function myfunction(){ var username = document.getElementById('username').value; var password = document.getElementById('password').value; jQuery.ajax({ type: "POST", url: 'http://localhost/Gardening-System/select_user.php', dataType: 'json', data: {uname: username, psw: password }, success: function (obj, textstatus) { if (!('error' in obj)) { var user = obj.result; // Define user variable here document.cookie = "username=" + username; // Set the cookie window.alert("Logged in as: " + username); // Display the logged-in username in an alert window.location.href = "index.html"; } else { console.log(obj.error); } }, error: function (xhr, status, error) { window.alert("AJAX request failed: " + error); // Handle AJAX request errors } }); } </script>
对应的后端select_user.php负责查询数据库验证用户,逻辑是验证通过后返回用户名给前端,由前端设置Cookie:
<?php header('Content-type: application/json'); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $uname = $_POST['uname']; $psw = $_POST['psw']; // Database details // Localhost address $username = "root"; $password = ""; $dbname = "Gardening_System"; // Creating a connection $con = mysqli_connect($host, $username, $password, $dbname); // echo ("checkpoint 1"); // Ensuring connection is made if (!$con) { die("Connection failed: " . mysqli_connect_error()); } // Sanitize user inputs to prevent SQL injection $uname = mysqli_real_escape_string($con, $uname); $psw = mysqli_real_escape_string($con, $psw); // Checking if the username and password combination exists in the database $checkQuery = "SELECT * FROM Username_Password WHERE username= '$uname' AND password= '$psw'"; // mysqli_stmt_bind_param($stmt, "ss", $uname, $psw); // mysqli_stmt_execute($stmt); $checkResult = mysqli_query($con, $checkQuery); // echo ("checkpoint 2"); if (mysqli_num_rows($checkResult) > 0) { $userData = mysqli_fetch_assoc($checkResult); $response = array('success' => true, 'result' => $userData["username"]); echo json_encode($response); // echo ("checkpoint 3"); if (setcookie($uname)){ header("Location: http://localhost/Gardening-System/index.html"); } } else { // Return an error message in JSON format $response = array('error' => 'User does not exist'); echo json_encode($response); } mysqli_close($con); } else { // If the request method is not POST, return an error message $response = array('error' => 'Invalid request method'); echo json_encode($response); } ?>
实际测试时,登录后页面能跳转到主页,但Cookie没保存也无法显示,请问问题出在哪?
问题原因分析
前端Cookie设置缺少核心属性
你用document.cookie = "username=" + username设置Cookie时,没指定path属性。默认情况下Cookie的path是当前页面的路径,如果登录页和主页不在同一路径(比如登录页在/login,主页在根目录),主页就读不到这个Cookie。另外也没设置max-age或expires,Cookie会变成会话级的,关闭浏览器就消失。后端多余操作打乱逻辑
后端验证通过后,执行的setcookie($uname)用法完全错误——setcookie第一个参数是Cookie名称,你把用户名当成名字传了;而且还在返回JSON之后做header跳转,这会导致前端同时接收JSON和被后端强制跳转,直接打乱了前端自己设置Cookie+跳转的逻辑。后端数据库连接变量未定义
后端里mysqli_connect($host, ...)的$host变量没定义,应该补上$host = "localhost";,虽然这可能没影响到你这次测试,但会导致数据库连接失败的隐患。
修复方案
前端修改
把Cookie设置代码改成:
document.cookie = "username=" + username + "; path=/; max-age=86400"; // path设为根目录,有效期1天
后端修改
删掉验证通过后的setcookie和header跳转代码,只保留返回JSON的逻辑(前端已经负责跳转和设置Cookie了):
if (mysqli_num_rows($checkResult) > 0) { $userData = mysqli_fetch_assoc($checkResult); $response = array('success' => true, 'result' => $userData["username"]); echo json_encode($response); // 删掉以下两行多余代码 // if (setcookie($uname)){ // header("Location: http://localhost/Gardening-System/index.html"); // } }
同时补上$host变量的定义:
// Database details $host = "localhost"; // 新增这行 $username = "root"; $password = ""; $dbname = "Gardening_System";
内容的提问来源于stack exchange,提问作者Bumblebee

