点击contacts-list用户加载聊天数据失败:Ajax与PHP代码问题排查求助
问题排查与修复方案
我看了你的代码,发现几个关键问题导致聊天数据无法正常加载,咱们一步步来解决:
前端脚本(chat.js)的核心错误
1. 元素获取与事件绑定错误
你当前的代码尝试获取一个不存在的#user元素,而且用户列表是动态生成的(通过setInterval拉取),直接绑定固定元素的点击事件根本不会生效。正确的做法是用事件委托,给父容器contacts-list绑定点击事件,然后获取点击的子元素的data-id。
2. 错误的参数传递方式
你直接把dataID通过xhr.send(dataID)发送,但后端期望接收POST请求里的dataId参数。这种发送方式后端无法正确解析,需要用表单格式的数据传递参数。
3. 混用jQuery与原生JS的语法错误
$('#elementId').getAttribute('data-id')是错误写法——jQuery对象没有getAttribute方法,而且这里根本不需要jQuery,直接用原生JS处理即可。
后端PHP(getChat.php)的错误
代码里的$outgoing_id变量没有定义,导致判断$row['out_msg_id'] === $outgoing_id时会报错,应该从预设值(比如HTML里的固定值1)或者session中赋值。
修正后的完整代码
前端chat.js
const usersList = document.querySelector(".contacts-list"), chatBox = document.querySelector(".direct-chat-messages"); // 用事件委托监听用户列表的点击事件 usersList.addEventListener('click', (e) => { // 确保点击的是带有data-id的用户项 const userItem = e.target.closest('[data-id]'); if (!userItem) return; const dataID = userItem.getAttribute('data-id'); let xhr = new XMLHttpRequest(); xhr.open("POST", "../system/ajax/chat/getChat.php", true); // 设置请求头,告诉后端接收的是表单数据 xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); xhr.onload = () => { if(xhr.readyState === XMLHttpRequest.DONE){ if(xhr.status === 200){ let data = xhr.response; console.log(data); chatBox.innerHTML = data; // 可选:自动滚动到最新消息位置 chatBox.scrollTop = chatBox.scrollHeight; } } } // 发送格式化的表单参数 xhr.send(`dataId=${encodeURIComponent(dataID)}`); }); setInterval(() =>{ let xhr = new XMLHttpRequest(); xhr.open("GET", "../system/ajax/chat/getChatUsers.php", true); xhr.onload = ()=>{ if(xhr.readyState === XMLHttpRequest.DONE){ if(xhr.status === 200){ let data = xhr.response; usersList.innerHTML = data; } } } xhr.send(); }, 500);
后端getChat.php
function GetChat() { global $dbc; session_start(); if(isset($_SESSION['username'])){ // 定义当前用户的outgoing_id,这里用你预设的固定值1,也可以从session中获取 $outgoing_id = '1'; // 接收前端传递的dataId参数,做安全处理 $incoming_id = mysqli_real_escape_string($dbc, $_POST['dataId'] ?? ''); $output = ""; $q = " SELECT * FROM chat WHERE (out_msg_id = '$outgoing_id' AND in_msg_id = '$incoming_id') OR (out_msg_id = '$incoming_id' AND in_msg_id = '$outgoing_id') ORDER BY msg_id "; $r = mysqli_query($dbc, $q); if(mysqli_num_rows($r) > 0){ while($row = mysqli_fetch_assoc($r)){ if($row['out_msg_id'] === $outgoing_id){ // 自己发送的消息 $output .= '<div class="msg-outgoing"> <div class="msg-info clearfix"> <span class="msg-name pull-right">You</span> <span class="msg-timestamp pull-left">'.date("dM y h:ia", strtotime($row['msg_dt'])).'</span> </div> <div class="msg-text"> '.$row['msg'].' </div> </div>'; }else{ // 对方发送的消息 $output .= '<div class="msg-incoming"> <div class="msg-info clearfix"> <span class="msg-name pull-left">Admin</span> <span class="msg-timestamp pull-right">'.date("dM y h:ia", strtotime($row['msg_dt'])).'</span> </div> <div class="msg-text"> '.$row['msg'].' </div> </div>'; } } echo $output; } else { // 无聊天记录时的提示 echo '<div class="text-center text-muted">No messages yet. Start a conversation!</div>'; } }else{ header('Location: ../'); exit(); } exit(); } // 记得调用函数执行逻辑 GetChat();
额外注意事项
- 确保
getChatUsers.php返回的用户列表每个<li>元素都正确带有data-id属性,比如:<li data-id="2">用户名称</li> - 开发时打开浏览器开发者工具(F12)的Network标签,查看请求状态和响应内容,能快速定位问题
- 为了提升安全性,后续建议使用MySQLi预编译语句替代
mysqli_real_escape_string,更彻底地防止SQL注入
内容的提问来源于stack exchange,提问作者Kumarjit
相关产品推荐
相关产品推荐

