Node+Express+PostgreSQL动态渲染查询结果为HTML表格问题排查
问题定位
你的代码存在两个核心错误,导致真实数据无法渲染:
- 后端路由逻辑冲突:你在
/machines路由中完成数据库查询后,没有将查询结果返回给前端,直接调用res.sendFile返回了静态HTML文件,前端根本拿不到数据库查询出的JSON数据。你之前注释掉的res.json(query.rows)是返回数据的正确写法,但和返回页面的逻辑不能放在同一个路由里,二者只能执行一个。 - 前端逻辑错误:你直接调用
buildTable(query)时,浏览器上下文里根本不存在query这个变量;即便拿到了后端返回的数据,你循环取值时多写了一层.rows,会直接报找不到属性的错误。
修正方案
1. 调整后端路由,拆分页面返回和数据返回逻辑
把返回静态页面和返回JSON数据拆成两个独立路由,一个负责给浏览器返回HTML文件,另一个专门提供数据接口:
const express = require ("express"); const app = express (); const port = 12345; const pool = require ("./postgres"); app.use(express.json()) // 根路径负责返回表格页面 app.get("/", (req, res) => { res.sendFile(__dirname + '/table.html'); }) // 独立数据接口,返回查询到的JSON结果 app.get("/api/machines", async(req,res)=> { try { const query = await pool.query (`SELECT br_ap,sticker,total_deposit*dn as "Uplata",total_withdraw*dn as "Isplata", COALESCE(total_deposit,0)*dn - COALESCE(total_withdraw,0)*dn as "TOTAL" ,lok FROM public.get_act_sab('03-04-2022 12:00', '05-05-2022 12:00') where lok='Lebane' order by br_ap`); res.json(query.rows); // 保留你原来的测试打印逻辑即可 console.table(query.rows); console.log("Broj aparata je: "+query.rowCount) console.log(query.rows[0]) console.log(query.rows[0].sticker) } catch (err) { console.error(err.message); res.status(500).json({error: err.message}) } }) app.listen(port,() => { console.log("Server up and running on port " +port) });
2. 调整前端代码,主动拉取数据后再渲染
删掉原来无意义的buildTable(query)调用,等页面加载完成后,主动请求上面写好的数据接口,拿到数据后清空测试行再渲染真实内容:
<!DOCTYPE html> <head> </head> <body> <table style="margin-left:auto;margin-right:auto;"> <thead> <tr> <th style="padding: 20px;"> Broj aparata</th> <th style="padding: 20px;"> Sticker</th> <th style="padding: 20px;"> Uplata</th> <th style="padding: 20px;"> Isplata</th> <th style="padding: 20px;"> Total IN-OUT</th> <th style="padding: 20px;"> Lokacija </th> </tr> </thead> <tbody id="myTable"> <!-- 原来的硬编码测试行可以删掉,渲染时会自动清空 --> <tr> <td style="padding: 20px;text-align:right;">1</td> <td style="padding: 20px;text-align:right;">1</td> <td style="padding: 20px;text-align:right;">1</td> <td style="padding: 20px;text-align:right;">1</td> <td style="padding: 20px;text-align:right;">1</td> <td style="padding: 20px;text-align:right;">1</td> </tr> </tbody> </table> <script> // 页面加载完成后自动拉取数据渲染 document.addEventListener('DOMContentLoaded', async () => { const response = await fetch('/api/machines'); const tableData = await response.json(); buildTable(tableData); }) function buildTable(data) { const table = document.getElementById("myTable"); // 先清空原有测试内容 table.innerHTML = ''; // 注意data本身就是行数组,直接取索引下的字段即可 for (let i = 0; i < data.length; i++) { const row = `<tr> <td style="padding: 20px;text-align:right;">${data[i].br_ap}</td> <td style="padding: 20px;text-align:right;">${data[i].sticker}</td> <td style="padding: 20px;text-align:right;">${data[i].Uplata}</td> <td style="padding: 20px;text-align:right;">${data[i].Isplata}</td> <td style="padding: 20px;text-align:right;">${data[i].TOTAL}</td> <td style="padding: 20px;text-align:right;">${data[i].lok}</td> </tr>` table.innerHTML += row } } </script> </body> </html>
验证方式
修改完成后重启Node服务,直接访问http://localhost:12345即可看到渲染完成的真实表格数据;你也可以访问http://localhost:12345/api/machines确认数据接口正常返回JSON结果。
内容的提问来源于stack exchange,提问作者Vojislav Medic
相关产品推荐
相关产品推荐

