
本文详解如何通过 javascript 的 `fetch()` 正确读取本地 json 文件并动态生成 `
在构建基于静态资源的 WiFi 密码管理页面时,一个常见需求是:从 data/data.json 中读取房间信息,并自动填充到
✅ 正确实现要点
确保 DOMContentLoaded 仅监听一次
原代码中若存在两处 document.addEventListener('DOMContentLoaded', loadRoomNumbers),会导致函数被调用两次(甚至可能因 DOM 已就绪而部分执行失败)。应严格保证该监听器全局唯一。推荐使用 async/await 提升可读性与错误控制力
相比 .then().catch() 链式调用,async/await 更直观,且能自然使用 try/catch 捕获网络异常、JSON 解析失败等各类错误。必须校验 fetch 响应状态与数据结构
response.ok 仅表示 HTTP 状态码在 200–299 范围;若 JSON 文件路径错误(如 404)、MIME 类型不匹配(如服务器未返回 application/json),或文件内容非法(如末尾多逗号),均会导致后续失败。
以下是经过验证的完整解决方案:
Select your room:
// JavaScript(推荐写法)
document.addEventListener('DOMContentLoaded', loadRoomNumbers);
async function loadRoomNumbers() {
const roomSelect = document.getElementById('room');
try {
const response = await fetch('data/data.json');
// ① 检查 HTTP 状态
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
// ② 解析 JSON —— 若格式错误会在此抛出 SyntaxError
const roomsData = await response.json();
// ③ 验证数据是否为数组(防意外空响应或对象)
if (!Array.isArray(roomsData)) {
throw new Error('Expected JSON array, got: ' + typeof roomsData);
}
// ④ 清空默认选项以外的内容(可选,增强健壮性)
roomSelect.innerHTML = '';
// ⑤ 动态添加选项
roomsData.forEach(roomData => {
if (roomData.Room) { // 防止缺失 Room 字段的对象导致空白选项
const option = document.createElement('option');
option.value = roomData.Room;
option.textContent = roomData.Room;
roomSelect.appendChild(option);
}
});
} catch (error) {
console.error('❌ Failed to load room list:', error);
// 可选:向用户提示友好错误(如显示警告 banner)
// alert('无法加载房间列表,请检查网络或联系管理员。');
}
}⚠️ 常见陷阱与调试建议
- 路径问题:确认 data/data.json 相对于 HTML 文件的路径正确。可在浏览器开发者工具的 Network 标签页中查看该请求是否返回 200,或直接访问 http://localhost:8000/data/data.json 验证。
- CORS 限制:若直接双击打开 HTML(file:// 协议),现代浏览器会阻止 fetch 请求本地文件。务必通过本地服务器运行(如 VS Code 的 Live Server 插件、npx serve 或 Python 的 python -m http.server)。
- JSON 编码问题:确保 data.json 保存为 UTF-8 无 BOM 格式,避免解析失败。
- DOM 元素不存在:document.getElementById('room') 返回 null 时,说明 HTML 中 id="room" 的
✅ 总结
下拉列表无数据显示,90% 源于异步加载未完成或错误静默失败。采用 async/await + try/catch 结构,配合 HTTP 状态与数据类型双重校验,不仅能快速定位问题(如 404、SyntaxError、null 引用),还能显著提升代码可维护性。切记:永远不要假设 fetch 一定成功,也永远不要忽略 DOM 元素是否存在。










