使用res.json(data)返回JSON时直接显示在浏览器而非传给前端JS的问题
问题
在Node.js(Express+MySQL)后端通过res.json(data)返回JSON对象时,浏览器直接显示JSON内容,未被前端原生JavaScript代码接收处理。相关代码如下:
后端Node.js代码
app.post('/register', async (req, res) => { db.query('SELECT email FROM users WHERE email = ?', [req.body.mail], async (err, result) => { if (err) throw err; if (result[0]) { console.log('Mail already used') // 此日志正常输出 var data = { status: 'error', error: 'This email is already being used' } res.json(data); // 省略后续代码 } }) })
前端原生JavaScript代码
const form = document.getElementById('register') form.addEventListener('submit', (event) => { event.preventDefault() const formData = new FormData(form) fetch("/register", { method: 'POST', body: formData }) .then(response => response.json()) .then(data => { document.getElementById('error').style.display = "block" document.getElementById('error').innerText = data.error console.log(data); }) .catch(error => { console.error(error) }) })
HTML代码
<form id="register" action="/register" method="POST" > <div class="txt name"> <input type="text" name="name" id='name' required> <label>name</label> </div> <div class="txt mail"> <input type="text" name="mail" id="mail" required> <label>Mail</label> </div> <div class="txt password"> <input type="password" name="password" id="password" required> <label>Password</label> </div> <div class="txt confirm"> <input type="password" name="confirm" id="confirm" required> <label>Confirm Password</label> </div> <div class="btn"> <input type="submit" id="btn" value="Register"> </div> </form>
解决方法
核心问题是表单默认提交行为未被有效阻止,导致浏览器直接跳转到action地址并显示响应,而非走异步请求流程。按以下步骤修复:
确保表单提交事件被正确拦截
- 确认JS代码在DOM加载完成后执行:将JS代码放在
</body>标签前,或用DOMContentLoaded包裹,避免因DOM未加载完成导致事件绑定失败:document.addEventListener('DOMContentLoaded', () => { const form = document.getElementById('register') form.addEventListener('submit', (event) => { event.preventDefault(); // 后续fetch请求代码 }) }) - 检查页面是否有其他监听表单提交的代码,避免事件传播被干扰。
- 确认JS代码在DOM加载完成后执行:将JS代码放在
配置后端解析FormData
- Express默认不处理
multipart/form-data类型的请求体(FormData属于此类),需安装multer中间件解析:
后端代码配置:npm install multerconst multer = require('multer'); const upload = multer(); // 仅解析数据,不保存文件 app.post('/register', upload.none(), async (req, res) => { // 此时req.body可正常获取表单字段 db.query('SELECT email FROM users WHERE email = ?', [req.body.mail], (err, result) => { // 原有业务逻辑 }) }) - 若未解析FormData,
req.body.mail会是undefined,导致查询逻辑异常,影响响应返回。
- Express默认不处理
验证异步请求是否发送
- 打开浏览器开发者工具(F12)的「网络」标签,点击注册按钮后,查看是否有
/register的POST请求。若无请求,说明事件绑定失败,表单走了默认提交流程。
- 打开浏览器开发者工具(F12)的「网络」标签,点击注册按钮后,查看是否有
内容的提问来源于stack exchange,提问作者Pada iOS
相关产品推荐
相关产品推荐

