You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现关联Oracle数据库的DOM表格数据动态无刷新更新?

实现前端表格无刷新动态更新的方案

下面是几种可行的实现方案,从快速改造到高效实时场景都有覆盖:

方案一:定时Fetch轮询(快速改造现有代码)

这是门槛最低的方案,不需要大幅改动现有架构,通过定时调用API获取最新数据,对比后更新表格。

改造步骤:

  • 先移除页面自动刷新的<meta http-equiv="refresh" content="5">
  • 把数据获取逻辑封装成独立函数,用setInterval定时执行
  • 记录最后一次获取的最新数据标识(比如时间、唯一ID),只新增变化的数据,避免重复渲染整个表格

修改后的前端代码示例:

<!DOCTYPE html>
<html lang="pt-br">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Apontamentos da Produção</title>
  <link rel="stylesheet" type="text/css" href="styles.css" media="screen" />
</head>
<body>
  <div id="data"></div>
  <div class="grid-container">
    <div class="container">
      <div class="texto"> PAINEL-1 | APONTAMENTOS DA PRODUÇÃO</div>
      <div class="clock"></div>
    </div>
  </div>
  <br>
  <table id="table" class="tablePrincipal">
    <tr class="trPrincipal">
      <th class="th2" style="width: 11%;">Data</th>
      <th class="th2" style="width: 8%; ">Hora</th>
      <th class="th2" style="width: 5%;">Orig.</th>
      <th class="th2" style="width: 8%;">O.P.</th>
      <th class="th2" style="width: 10%;">Produto</th>
      <th class="th2" style="width: 8%;">Deriv.</th>
      <th class="th2" style="width: 9%;">Peso (TN)</th>
      <th class="th2" style="width: 7%;">Refugo (TN)</th>
      <th class="th2" style="width: 13%;">Lote</th>
      <th class="th2" style="width: 60%;">Operador</th>
    </tr>
  </table>
  <script>
    let lastLatestTime = null; // 记录最后一条数据的时间,用来判断是否有新增
    const table = document.getElementById('table');

    // 封装数据获取与更新逻辑
    async function updateTable() {
      try {
        const response = await fetch('http://localhost:3000/teste');
        const data = await response.json();
        if (!data.length) return;

        // 假设返回的第一条数据是最新的,取Hora列作为时间标识(可换成唯一ID)
        const currentLatestTime = data[0][1];

        if (!lastLatestTime) {
          // 首次加载:清空现有行(除表头),渲染前7条数据
          while (table.rows.length > 1) {
            table.deleteRow(1);
          }
          for (let i = 0; i < Math.min(7, data.length); i++) {
            addRow(data[i]);
          }
        } else if (currentLatestTime !== lastLatestTime) {
          // 有新数据:插入到表格顶部,保持最多7行
          addRow(data[0], true);
          if (table.rows.length > 8) {
            table.deleteRow(table.rows.length - 1);
          }
        }

        lastLatestTime = currentLatestTime;
      } catch (error) {
        console.error('更新表格失败:', error);
      }
    }

    // 新增行到表格的工具函数
    function addRow(rowData, insertAtTop = false) {
      const row = table.insertRow(insertAtTop ? 1 : table.rows.length);
      const cells = [];
      for (let i = 0; i < 10; i++) {
        cells.push(row.insertCell(i));
      }
      cells[0].innerHTML = rowData[0];
      cells[1].innerHTML = rowData[1];
      cells[2].innerHTML = rowData[2];
      cells[3].innerHTML = rowData[3];
      cells[4].innerHTML = rowData[4];
      cells[5].innerHTML = rowData[5];
      cells[6].innerHTML = rowData[6];
      cells[7].innerHTML = rowData[7];
      cells[8].innerHTML = rowData[8];
      cells[9].innerHTML = rowData[9];
    }

    // 页面初始化+定时更新
    window.onload = function() {
      updateTable();
      setInterval(updateTable, 5000); // 每5秒查询一次,可根据需求调整间隔
    };
  </script>
</body>
</html>

方案二:WebSocket实时推送(低延迟实时更新)

如果需要更低延迟的实时效果,推荐用WebSocket。后端在数据库有新数据入库时,主动推送给前端,前端接收消息后直接更新表格。

后端(Node.js)示例:

先安装ws库:npm install ws

const express = require('express');
const WebSocket = require('ws');
const app = express();
const server = require('http').createServer(app);
const wss = new WebSocket.Server({ server });

// 替换成你的Oracle查询函数,获取最新一条入库数据
async function getLatestProductionData() {
  // 这里写你的Oracle查询逻辑
  const latestData = await yourOracleQueryMethod();
  return latestData;
}

// 监听WebSocket连接
wss.on('connection', (ws) => {
  console.log('客户端已连接');

  // 定时检查数据库新数据(也可以改成数据库插入触发器触发推送)
  const checkInterval = setInterval(async () => {
    const latestData = await getLatestProductionData();
    if (latestData) {
      ws.send(JSON.stringify(latestData));
    }
  }, 2000); // 每2秒检查一次,可调整

  ws.on('close', () => {
    console.log('客户端断开连接');
    clearInterval(checkInterval);
  });
});

server.listen(3000, () => {
  console.log('服务器运行在端口3000');
});

前端修改示例:

const table = document.getElementById('table');
let ws;

function initWebSocket() {
  ws = new WebSocket('ws://localhost:3000');

  ws.onopen = () => console.log('WebSocket连接成功');

  ws.onmessage = (event) => {
    const newData = JSON.parse(event.data);
    // 插入新数据到表格顶部
    addRow(newData, true);
    // 保持最多7行数据
    if (table.rows.length > 8) {
      table.deleteRow(table.rows.length - 1);
    }
  };

  ws.onerror = (error) => console.error('WebSocket错误:', error);

  ws.onclose = () => {
    console.log('连接断开,3秒后重连');
    setTimeout(initWebSocket, 3000);
  };
}

// 复用方案一中的addRow函数
function addRow(rowData, insertAtTop = false) {
  const row = table.insertRow(insertAtTop ? 1 : table.rows.length);
  const cells = [];
  for (let i = 0; i < 10; i++) {
    cells.push(row.insertCell(i));
  }
  cells[0].innerHTML = rowData[0];
  cells[1].innerHTML = rowData[1];
  cells[2].innerHTML = rowData[2];
  cells[3].innerHTML = rowData[3];
  cells[4].innerHTML = rowData[4];
  cells[5].innerHTML = rowData[5];
  cells[6].innerHTML = rowData[6];
  cells[7].innerHTML = rowData[7];
  cells[8].innerHTML = rowData[8];
  cells[9].innerHTML = rowData[9];
}

window.onload = initWebSocket;

方案三:Server-Sent Events (SSE)(单向推送,实现简单)

SSE是HTTP协议的扩展,适合后端单向向前端推送数据,无需额外WebSocket库,实现成本低。

后端(Node.js)示例:

const express = require('express');
const app = express();

app.get('/sse', async (req, res) => {
  // 设置SSE响应头
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.setHeader('Connection', 'keep-alive');

  // 发送最新数据的函数
  const sendLatestData = async () => {
    const latestData = await yourOracleQueryMethod(); // 查询最新数据
    if (latestData) {
      res.write(`data: ${JSON.stringify(latestData)}\n\n`);
    }
  };

  // 首次发送数据
  await sendLatestData();

  // 定时推送新数据
  const interval = setInterval(sendLatestData, 2000);

  // 客户端断开时清理定时器
  req.on('close', () => {
    clearInterval(interval);
    res.end();
  });
});

app.listen(3000, () => {
  console.log('服务器运行在端口3000');
});

前端修改示例:

const table = document.getElementById('table');

function initSSE() {
  const eventSource = new EventSource('http://localhost:3000/sse');

  eventSource.onmessage = (event) => {
    const newData = JSON.parse(event.data);
    addRow(newData, true);
    if (table.rows.length > 8) {
      table.deleteRow(table.rows.length - 1);
    }
  };

  eventSource.onerror = (error) => {
    console.error('SSE错误:', error);
    eventSource.close();
    setTimeout(initSSE, 3000); // 断开后自动重连
  };
}

// 复用addRow函数
function addRow(rowData, insertAtTop = false) {
  const row = table.insertRow(insertAtTop ? 1 : table.rows.length);
  const cells = [];
  for (let i = 0; i < 10; i++) {
    cells.push(row.insertCell(i));
  }
  cells[0].innerHTML = rowData[0];
  cells[1].innerHTML = rowData[1];
  cells[2].innerHTML = rowData[2];
  cells[3].innerHTML = rowData[3];
  cells[4].innerHTML = rowData[4];
  cells[5].innerHTML = rowData[5];
  cells[6].innerHTML = rowData[6];
  cells[7].innerHTML = rowData[7];
  cells[8].innerHTML = rowData[8];
  cells[9].innerHTML = rowData[9];
}

window.onload = initSSE;

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:35:23