html中fetch('/api/data')报错主因是file://协议下被浏览器拦截,须部署于http://服务器(如python -m http.server);后端需返回合法json及access-control-allow-origin头,前端须检查response.ok并妥善处理错误。

HTML 里写 fetch('/api/data') 就报错?先看协议和部署位置
浏览器拒绝执行请求,大概率不是代码写错了,而是 HTML 文件正用 file:// 协议双击打开。这种模式下,fetch 直接被拦截,控制台显示 Failed to fetch 或 net::ERR_FAILED。
必须把 index.html 放进 Web 服务器环境运行,比如:
- 本地开发:用
python3 -m http.server 8000启一个静态服务,然后访问http://localhost:8000/index.html - 生产环境:Nginx/Apache 配置好 root 路径,确保 HTML 和后端 API 在同一域名下(或至少同源)
- 若后端 API 在
http://localhost:3000,前端也得从http://localhost:3000加载 HTML,否则触发跨域
后端接口返回数据但页面空白?检查响应头和 JSON 格式
即使 fetch 看似成功,也可能因后端没设正确响应头或返回了非 JSON 内容,导致 .json() 报错或静默失败。
后端必须明确声明:
Content-Type: application/json; charset=utf-8-
Access-Control-Allow-Origin: *(开发时)或具体域名(生产时) - 响应体是合法 JSON:不能有 PHP 的
echo "debug info";混在前面,也不能漏掉json_encode()包裹
简单验证方式:直接在浏览器地址栏打开 http://localhost:3000/api/data,看是否显示纯 JSON(如 [{"id":1,"name":"Alice"}]),且无 HTML 标签或错误提示。
前端渲染时数据没插入 DOM?别跳过 error 处理和空值判断
fetch 成功不代表数据可用;网络通、状态码 200、JSON 解析成功,三者缺一不可。常见疏漏:
- 没加
catch(),错误全吞掉,控制台也看不到提示 - 后端返回空数组或
null,但前端代码假设一定有data[0].name,直接报Cannot read property 'name' of undefined - 用
innerHTML = data.map(...).join('')但 data 是对象而非数组(比如后端返回{"result": [...]})
最小安全写法示例:
fetch('/api/users')
.then(r => {
if (!r.ok) throw new Error(`HTTP ${r.status}`);
return r.json();
})
.then(data => {
if (!Array.isArray(data)) throw new Error('Expected array');
document.querySelector('#list').innerHTML = data
.map(u => `<div>ID: ${u.id}, Name: ${u.name || '-'}</div>`)
.join('');
})
.catch(err => console.error('Render failed:', err));
为什么不能把数据库连接写在 HTML 里?安全与架构边界必须守住
有人试过把 mysql2.connect() 或数据库地址硬编码进 JS,或者用 eval() 动态拼 SQL——这等于把数据库账号密码、内网地址、表结构全暴露给用户。任何懂 F12 的人都能拿到并连你生产库。
真正该隔离的三件事:
- 数据库凭证只出现在后端配置中(如
process.env.DB_PASSWORD或.env文件),绝不进前端构建产物 - 所有 SQL 查询必须参数化,禁止字符串拼接,哪怕只是
WHERE id = ${id}也不行 - 后端接口要收敛权限:/api/users 返回全部用户?不行;应按角色返回,或加
user_id = ?参数校验归属
最简链路可靠,但最容易被绕过的,恰恰是“图省事少写一行校验”或“先跑通再说”的那一行代码。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











