
本文详解如何在网页加载时通过 get 请求从后端 api 获取数据,并动态渲染到 html 表格中,实现前后端联动的数据展示闭环,适用于初学者构建全栈 crud 应用。
本文详解如何在网页加载时通过 get 请求从后端 api 获取数据,并动态渲染到 html 表格中,实现前后端联动的数据展示闭环,适用于初学者构建全栈 crud 应用。
在你已成功实现 POST 提交表单数据至数据库的基础上,GET 请求的核心作用是“读取”而非“写入”——它负责在页面首次加载、用户关闭弹窗后刷新视图,或点击“刷新列表”按钮时,从服务端拉取最新数据并更新表格内容。你当前的 script.js 中注释掉的 GET 尝试逻辑方向正确,但缺失了三个关键环节:触发时机(何时发请求)、响应处理(如何解析 JSON)、DOM 渲染(怎样填入表格)。下面我们将一步步补全。
✅ 一、在页面加载完成时发起 GET 请求
使用 DOMContentLoaded 事件确保 DOM 构建完毕后再执行请求,避免因元素未就绪导致操作失败:
// script.js —— 新增:页面加载时获取全部数据并渲染表格
document.addEventListener("DOMContentLoaded", async () => {
try {
const response = await fetch('http://my_data:3000/mine_info');
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const rows = await response.json();
// 清空原有表格主体(保留表头)
const tableBody = document.querySelector('#mine_info tbody') ||
document.querySelector('#mine_info').insertRow(0).parentNode;
// 如果没有 tbody,直接清空除第一行(表头)外的所有行
const table = document.querySelector('#mine_info');
while (table.rows.length > 1) {
table.deleteRow(1);
}
// 遍历数据,逐行插入
rows.forEach((row, index) => {
const tr = table.insertRow();
tr.innerHTML = `
<td><p>${index + 1}</p></td>
<td><p>${row.n_mine || ''}</p></td>
<td><p>${row.name_mine || ''}</p></td>
<td><p>${row.adress || ''}</p></td>
<td><p>${row.full_name_of_direcor || ''}</p></td>
<td><p>${row.phone_number || ''}</p></td>
`;
});
} catch (error) {
console.error('Failed to load mine info:', error);
alert('⚠️ 数据加载失败,请检查后端是否运行正常(如 http://my_data:3000/mine_info 是否可访问)');
}
});? 注意字段映射一致性:你的后端 getMineinfo 返回的是数据库列名(如 n_mine, name_mine),而前端表格期望显示这些字段。请确认 PostgreSQL 表结构中的列名与 row.xxx 访问路径完全匹配(大小写敏感),否则会渲染为空字符串。
✅ 二、优化表单提交后的自动刷新(无需整页重载)
你当前的 form.addEventListener('submit') 已正确阻止默认提交行为,并执行 POST。为提升用户体验,提交成功后应立即重新 GET 数据,使新增行实时出现在表格中,无需手动刷新页面:
立即学习“前端免费学习笔记(深入)”;
// 在 form.submit 的 try 块末尾添加(紧接在 POST 成功之后)
// ... POST 请求成功后 ...
console.log('✅ Row created successfully');
// 立即刷新表格数据
await loadMineInfo(); // 复用封装好的函数
// 关闭弹窗
form.classList.remove('open');
popup.classList.remove('popup_open');同时,将上述 GET 渲染逻辑提取为可复用函数:
async function loadMineInfo() {
const table = document.querySelector('#mine_info');
// 清空旧数据(保留表头)
while (table.rows.length > 1) table.deleteRow(1);
try {
const res = await fetch('http://my_data:3000/mine_info');
const data = await res.json();
data.forEach((r, i) => {
const tr = table.insertRow();
tr.innerHTML = `
<td><p>${i + 1}</p></td>
<td><p>${r.n_mine || ''}</p></td>
<td><p>${r.name_mine || ''}</p></td>
<td><p>${r.adress || ''}</p></td>
<td><p>${r.full_name_of_direcor || ''}</p></td>
<td><p>${r.phone_number || ''}</p></td>
`;
});
} catch (err) {
console.error('Load failed:', err);
}
}并在 DOMContentLoaded 中调用它:
document.addEventListener("DOMContentLoaded", () => {
loadMineInfo(); // 页面加载时首次拉取
});✅ 三、关键注意事项与调试建议
- CORS 配置已就绪:你已在 Express 中启用 app.use(cors()),确保浏览器允许跨域请求(若前端地址非 http://my_data:3000,需确认域名/端口一致或配置白名单)。
- 后端路由匹配:GET 请求地址 http://my_data:3000/mine_info 必须与 Express 中 app.get('/mine_info', ...) 完全一致(无尾部斜杠差异)。
-
HTML 结构健壮性:原始代码中 <table> 内无 <tbody>,但 insertRow() 默认在 <tbody> 中插入;若不存在,现代浏览器会自动创建,但显式添加更稳妥:
<table id="mine_info"> <thead> <tr>...</tr> </thead> <tbody></tbody> <!-- 显式声明 --> </table> - 错误防御:服务端返回非 2xx 状态码(如 500 错误)时,response.ok 为 false,应捕获并提示用户,而非静默失败。
- 调试技巧:在浏览器控制台直接运行 fetch('http://my_data:3000/mine_info').then(r => r.json()).then(console.log),验证 API 是否返回预期 JSON 数组。
✅ 总结
GET 请求不是“可选项”,而是前端数据驱动 UI 的基石。它让你的表格具备自更新能力:页面加载 → 拉取全量数据 → 用户新增 → POST 成功 → 自动再次 GET → 表格实时刷新。这一闭环构成了现代 Web 应用的基本交互范式。你现在已掌握前后端通信的两大支柱(GET 读取 / POST 写入),下一步可延伸实现:按 ID 删除、编辑行内修改、分页加载等进阶功能。坚持下去,第一个全栈项目就在眼前!










