You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

请求协助:修复JavaScript渲染JSON至HTML Div标签的代码问题

解决JSON数据渲染到HTML的问题

我帮你梳理下代码里的核心问题,然后给出修改后的完整方案:

核心问题分析

  1. PHP输出格式错误:你用了Server-Sent Events(SSE)的输出格式,但JS是普通AJAX请求,导致无法正确解析JSON
  2. JS未解析JSON响应:直接把响应文本当作对象操作,实际是字符串,遍历逻辑失效
  3. HTML元素ID重复:每个设备行里的子元素(如trtypetrstatus)用了重复ID,违反HTML规范,无法精准定位
  4. 定时器重复创建:每次点击按钮都会新增一个定时器,导致重复请求

修改后的完整代码

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); // 每秒刷新一次
}

关键修改说明

  1. PHP:添加Content-Type响应头,直接输出纯净JSON,去掉了多余的data:前缀
  2. HTML:将重复的ID改为class,确保页面元素ID唯一性,同时调整名称显示结构更合理
  3. JS
    • 新增定时器管理,避免重复请求
    • JSON.parse解析响应文本为JS对象
    • 通过父元素的querySelector精准定位子元素,避免全局选择冲突
    • 添加错误捕获与日志,方便调试

测试时可以打开浏览器开发者工具(F12),查看Console和Network标签,确认请求是否成功、数据是否正确解析。

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

火山引擎 最新活动