HTML本身不能调用API,必须由JavaScript通过fetch等方法实现;常见渲染失败原因是未在HTTP服务下运行、未正确处理Promise链或DOM插入时机不当。

HTML 模板本身不能调用外部 API,所有数据拉取和渲染逻辑必须由 JavaScript 承担;直接在 index.html 里写 fetch() 却看不到数据,90% 是因为没跑在 HTTP 服务上,或没处理好 Promise 链与 DOM 插入时机。
为什么 fetch 写对了却没渲染到表格里
常见现象:控制台没报错、console.log(data) 能打出内容,但 document.getElementById('tbody').innerHTML 仍是空的。
- DOM 元素还没加载完就执行 JS —— 把脚本放在
</body>前,或监听DOMContentLoaded事件 -
response.json()是另一个 Promise,漏掉.then()或await,导致后续代码拿到的是 pending 状态的 Promise,不是真实数据 - API 返回结构嵌套(比如
{ results: [...] }),却直接遍历data,结果data.map报错TypeError: data.map is not a function - 用
innerHTML += "<tr>..."拼接多行,触发浏览器反复重排,大数据量时卡顿甚至丢行
fetch + 表格渲染的最小可靠写法
适用于 NASA、JSONPlaceholder 这类返回数组的公开 API,不依赖构建工具,开箱即用。
确保 HTML 中有 <table id="data-table"><thead></thead><tbody id="table-body"></tbody></table> 结构,JS 如下:
立即学习“前端免费学习笔记(深入)”;
async function renderTable() {
const tbody = document.getElementById('table-body');
try {
const res = await fetch('https://jsonplaceholder.typicode.com/posts?_limit=5');
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const data = await res.json();
// 假设 data 是数组,且每项有 id/title/body
const rows = data.map(item =>
`<tr>
<td>${item.id}</td>
<td>${item.title}</td>
<td>${item.body.substring(0, 40)}...</td>
</tr>`
).join('');
tbody.innerHTML = rows;
} catch (err) {
console.error(err);
tbody.innerHTML = '<tr><td colspan="3">加载失败,请检查网络或 API 地址</td></tr>';
}
}
document.addEventListener('DOMContentLoaded', renderTable);
- 用
async/await替代嵌套.then(),可读性高、错误统一捕获 - 显式检查
res.ok,避免把 404/500 当作成功响应 - 批量生成字符串再一次性赋值给
innerHTML,比循环appendChild快得多(小数据量下差异不明显,但习惯要对) - 注意 XSS 风险:如果 API 数据含用户输入内容,不能直接插进
innerHTML,得用textContent或转义函数
本地开发时 fetch 一直报 CORS 错误怎么办
错误信息典型为:Access to fetch at 'https://xxx' from origin 'null' has been blocked by CORS policy。
- 根本原因:你双击打开的
file://页面被浏览器禁止发起跨域请求 —— 这是安全限制,无法绕过 - 临时解法:用 Python 启一个本地服务器,例如终端运行
python3 -m http.server 8000,然后访问http://localhost:8000/index.html - 不要试图用 Chrome 的
--disable-web-security启动参数,它会禁用全部安全策略,且新版 Chrome 已不支持该方式 - 如果目标 API 不允许你的域名(比如只配了
Access-Control-Allow-Origin: https://myapp.com),前端无解,必须让后端改响应头或加代理
用 axios 替代 fetch 的实际收益在哪
不是“更高级”,而是解决几个 fetch 的隐性痛点:
-
axios默认自动解析 JSON,不用写response.json();fetch必须手动调,漏掉就拿不到数据 - HTTP 错误码(如 404、500)默认不 reject,
axios会自动抛异常,fetch得靠if (!res.ok) throw自己判断 - POST 提交 JSON 时,
axios自动加Content-Type: application/json,fetch必须手动写headers对象 - 但引入
axios意味着额外 5KB JS 加载,纯静态页面且只发 1–2 个 GET 请求时,fetch更轻量
真正容易被忽略的是:无论用 fetch 还是 axios,只要涉及用户输入内容插入 DOM,就必须做 HTML 转义;模板里直接插未过滤的 data.title,等于主动开 XE 漏洞。



















