请求协助:修复JavaScript渲染JSON至HTML Div标签的代码问题
解决JSON数据渲染到HTML的问题
我帮你梳理下代码里的核心问题,然后给出修改后的完整方案:
核心问题分析
- PHP输出格式错误:你用了Server-Sent Events(SSE)的输出格式,但JS是普通AJAX请求,导致无法正确解析JSON
- JS未解析JSON响应:直接把响应文本当作对象操作,实际是字符串,遍历逻辑失效
- HTML元素ID重复:每个设备行里的子元素(如
trtype、trstatus)用了重复ID,违反HTML规范,无法精准定位 - 定时器重复创建:每次点击按钮都会新增一个定时器,导致重复请求
修改后的完整代码
1. PHP后端(xhr.php)
<?php header('Content-Type: application/json'); // 必须声明响应类型为JSON $servername = "localhost"; $username = "root"; $password = ""; $dbname = "mydb1"; $array = array(); $conn = mysqli_connect($servername, $username, $password, $dbname); // 连接错误处理 if (!$conn) { die(json_encode(['error' => "Connection failed: " . mysqli_connect_error()])); } $sql = "SELECT * FROM dmaster"; $result = mysqli_query($conn, $sql); if (mysqli_num_rows($result) > 0) { while($row = mysqli_fetch_assoc($result)) { $arraynew = array( 'id' =>$row["dID"], 'dev_name' =>$row["dName"], 'dev_type' =>$row["dType"], 'access_code' =>$row["access_Code"], 'time_stamp'=>$row["time_Stamp"], 'status' =>$row["dStatus"], 'reading01' =>$row["dReading01"], 'reading02' =>$row["dReading02"] ); $arraynew = array_map('htmlentities',$arraynew); array_push($array,$arraynew); } } mysqli_close($conn); echo json_encode($array); // 直接输出纯净JSON,无额外前缀 ?>
2. HTML结构(修复重复ID问题)
<!-- 假设你用PHP循环输出此结构,外层div的ID是唯一的设备ID --> <div class="row mt-2 mb-2 height bg-dark text-light" id="<?php echo $row['dev_ID']; ?>"> <div class="col-3" > <div class="card height bg-dark" style="width: auto"> <div class="card-body" > <h6>Name : <span class="trname"></span></h6> <p class="trtype"></p> </div> </div> </div> <div class="col-2"> <div class="card height bg-dark" style="width: auto"> <div class="card-body"> <h6>Status</h6> <p class="trstatus"></p> </div> </div> </div> <div class="col-3"> <div class="card height bg-dark" style="width: auto"> <div class="card-body"> <h6>Reading 01</h6> <p class="trreading01"></p> </div> </div> </div> <div class="col-3"> <div class="card height bg-dark" style="width: auto"> <div class="card-body"> <h6>Reading 02</h6> <p class="trreading02"></p> </div> </div> </div> <div class="col-1"> <div class="card height bg-dark" style="width: auto"> <div class="card-body"> <h6>Dev</h6> </div> </div> </div> </div>
3. JavaScript代码(修复解析与DOM操作)
let intervalId; // 保存定时器ID,防止重复创建 document.getElementById('button').addEventListener('click', function() { // 点击按钮时先清除已有定时器,避免重复请求 if (intervalId) { clearInterval(intervalId); } loadReadings(); }); function loadReadings(){ intervalId = setInterval(function(){ const xhr = new XMLHttpRequest(); xhr.open('GET','xhr.php',true); // 获取数据用GET更符合语义 xhr.onload = function(){ if(this.status === 200){ try { const devices = JSON.parse(this.responseText); // 解析JSON为JS数组 console.log('获取到设备数据:', devices); devices.forEach(device => { const deviceRow = document.getElementById(device.id); if (!deviceRow) return; // 找不到对应设备行则跳过 // 通过父元素精准定位子元素(避免全局选择冲突) deviceRow.querySelector('.trname').textContent = device.dev_name; deviceRow.querySelector('.trtype').textContent = device.dev_type; deviceRow.querySelector('.trstatus').textContent = device.status; deviceRow.querySelector('.trreading01').textContent = device.reading01; deviceRow.querySelector('.trreading02').textContent = device.reading02; }); } catch (e) { console.error('JSON解析失败:', e); } } else { console.error('请求失败,状态码:', this.status); } }; // 处理网络错误 xhr.onerror = function() { console.error('网络请求出错,请检查后端服务'); }; xhr.send(); }, 1000); // 每秒刷新一次 }
关键修改说明
- PHP:添加
Content-Type响应头,直接输出纯净JSON,去掉了多余的data:前缀 - HTML:将重复的ID改为class,确保页面元素ID唯一性,同时调整名称显示结构更合理
- JS:
- 新增定时器管理,避免重复请求
- 用
JSON.parse解析响应文本为JS对象 - 通过父元素的
querySelector精准定位子元素,避免全局选择冲突 - 添加错误捕获与日志,方便调试
测试时可以打开浏览器开发者工具(F12),查看Console和Network标签,确认请求是否成功、数据是否正确解析。
内容的提问来源于stack exchange,提问作者NadeejaD




