为什么GET请求中req.body为空?附前后端代码示例
GET请求后端req.body为空对象的原因及解决办法
我在使用GET请求获取图表数据时,后端打印req.body显示为空对象{},想知道原因是什么,以下是我的前后端代码:
前端代码
const fetchData = () => { const options = { method: 'GET', url: 'http://localhost:1337/user/chart', headers: {'x-access-token': sessionStorage.getItem('token')}, body: [chartData.datasets] } axios.request(options).then((response) => { console.log(response) }).catch((error) => { console.error(error)}) }
后端代码
app.get('/user/chart', async (req, res) => { const token = req.headers['x-access-token'] if (!token){ return res.status(404).json({ success: false, msg: "Token not found" }); } try { const decoded = jwt.verify(token, process.env.access_secret) const email = decoded.email await User.updateOne( { email: email }, { $set: {} }, ) console.log(req.body) return res.status(200).json({message: 'ok', label:[]}) } catch (error) { console.log(error) res.json({ status: 'error', error: 'invalid token' }) } })
原因分析
- HTTP协议规范限制:GET请求的设计初衷是从服务器获取资源,协议本身不支持携带请求体(body)。虽然部分客户端工具允许手动设置GET请求的body,但绝大多数服务器框架(比如你用的Express)会直接忽略这部分内容,后端自然拿不到数据。
- Axios内部处理逻辑:就算你在Axios的GET请求配置里写了
body参数,Axios也会自动忽略该配置,不会把body内容发送给服务器。
解决办法
方案1:用查询参数传递数据(适合数据量小的场景)
把要传递的数据拼接到URL的查询参数里,Axios可通过params配置自动处理:
前端修改
const fetchData = () => { const options = { method: 'GET', url: 'http://localhost:1337/user/chart', headers: {'x-access-token': sessionStorage.getItem('token')}, // 复杂数据转成JSON字符串通过params传递 params: { datasets: JSON.stringify(chartData.datasets) } } axios.request(options).then((response) => { console.log(response) }).catch((error) => { console.error(error) }) }
后端修改
通过req.query获取查询参数,再解析JSON字符串:
app.get('/user/chart', async (req, res) => { const token = req.headers['x-access-token'] if (!token){ return res.status(404).json({ success: false, msg: "Token not found" }); } try { const decoded = jwt.verify(token, process.env.access_secret) const email = decoded.email await User.updateOne( { email: email }, { $set: {} }, ) // 解析查询参数中的JSON数据 const datasets = JSON.parse(req.query.datasets) console.log(datasets) return res.status(200).json({message: 'ok', label:[]}) } catch (error) { console.log(error) res.json({ status: 'error', error: 'invalid token' }) } })
方案2:改用POST请求(适合数据量大/结构复杂的场景)
POST请求支持携带请求体,更适合传递复杂数据:
前端修改
把请求方法改成POST,同时添加Content-Type头告知后端数据格式:
const fetchData = () => { const options = { method: 'POST', url: 'http://localhost:1337/user/chart', headers: { 'x-access-token': sessionStorage.getItem('token'), 'Content-Type': 'application/json' }, data: [chartData.datasets] // Axios POST推荐用data字段,request方法兼容body } axios.request(options).then((response) => { console.log(response) }).catch((error) => { console.error(error) }) }
后端修改
把路由改成POST,且确保已配置Express的JSON解析中间件(需加在路由之前):
// 配置JSON解析中间件,否则无法解析req.body app.use(express.json()) app.post('/user/chart', async (req, res) => { const token = req.headers['x-access-token'] if (!token){ return res.status(404).json({ success: false, msg: "Token not found" }); } try { const decoded = jwt.verify(token, process.env.access_secret) const email = decoded.email await User.updateOne( { email: email }, { $set: {} }, ) console.log(req.body) // 现在可正常获取数据 return res.status(200).json({message: 'ok', label:[]}) } catch (error) { console.log(error) res.json({ status: 'error', error: 'invalid token' }) } })
内容的提问来源于stack exchange,提问作者anon
相关产品推荐
相关产品推荐

