使用bodyParser后req.body仍为空的Express+MySQL API问题
嘿,我一眼就看出问题所在了——这其实是HTTP协议的规范导致的,不是你的代码写错了!
核心原因:GET请求不支持(也不应该用)请求体
HTTP协议里,GET请求的设计目的是从服务器获取资源,它本身就不携带请求体(request body)。虽然像Postman这类工具允许你给GET请求手动添加body,但这属于不符合标准的用法,而且Express的body-parser中间件也不会去解析GET请求的body内容,所以你打印req.body自然得到的是空对象{}。
至于你说Postman能正常返回用户JSON数据,那是因为你的接口逻辑是直接查询数据库并返回结果,这个返回和请求体完全无关——不管你有没有传body,只要接口能正常执行SQL查询,就会返回数据。
解决方案分两种情况:
1. 只是获取全量用户列表(不需要传参数)
那你现在的接口逻辑完全没问题,只是没必要去打印req.body,因为GET请求本来就不该有body。你可以把console.log(req.body)这行删掉,或者换成打印请求的其他信息(比如req.query)。
2. 需要根据参数筛选用户(比如按用户名查询)
这种情况应该用URL查询参数(query parameters),而不是请求体。举个修改后的代码示例:
app.get('/show', (req, res) => { // 从query中获取参数,比如请求地址是 /show?username=ujju const { username } = req.query; let sql = 'SELECT * from users'; // 如果有username参数,就添加筛选条件 if (username) { sql += ' WHERE username = ?'; } conn.query(sql, username ? [username] : [], (err, result) => { if (err) throw err; res.send(result.length > 0 ? result[0] : {}); }); // 这里打印query参数,而不是req.body console.log('请求参数:', req.query); });
测试的时候,在Postman里直接把参数拼在URL后面就行,不用加body。
3. 确实需要通过请求体传递复杂数据
如果你的业务场景必须用请求体(比如复杂的多条件筛选),那应该把接口改成POST请求,这样body-parser才会正常解析请求体内容。示例代码:
// 把GET改成POST app.post('/show', (req, res) => { // 现在就能正常拿到POST请求的body了 console.log('请求体:', req.body); const { username } = req.body; let sql = 'SELECT * from users'; if (username) { sql += ' WHERE username = ?'; } conn.query(sql, username ? [username] : [], (err, result) => { if (err) throw err; res.send(result.length > 0 ? result[0] : {}); }); });
测试的时候,在Postman里选择POST方法,然后在Body选项卡选raw -> JSON格式,输入参数即可。
最后提醒
尽量遵循HTTP协议的规范:GET用于获取资源,POST用于提交数据,这样不仅符合标准,也能避免这类奇怪的问题~
内容的提问来源于stack exchange,提问作者Ujwal Arak

