Express调用res.send报循环结构转JSON错误的原因及解决方案
问题原因
这个报错是你直接把axios的完整响应对象传给res.send()导致的:
- axios返回的响应对象除了接口返回的业务数据外,还包含请求上下文、socket连接、配置项等属性,这些属性存在循环引用关系(比如请求实例引用socket,socket又反向关联请求实例)
- Express的
res.send()方法处理对象类型参数时,会自动调用JSON.stringify()做序列化,JSON序列化不支持循环引用结构,就会抛出你看到的错误 console.log()可以正常打印是因为控制台输出逻辑对循环引用做了兼容处理,不会强行序列化整个对象结构
修复方案
你只需要返回axios响应对象里的data字段即可,这个字段就是你调用第三方接口拿到的纯业务数据,没有循环引用。
有两种修改方式二选一即可:
方式1:修改getData()的返回值
const getData = async route => { const config = { headers: { 'Authorization': `Bearer ${TOKEN}`, 'Content-Type': 'application/json;charset=utf-8' } } let corrRoute = route[0] == '/' ? route : '/' + route // 只返回响应体的data字段 return (await axios(`${URL}${corrRoute}?api_key=${API_KEY}`, config)).data }
方式2:修改接口返回时的取值
app.post('/api', async (req, res) => { let { route } = req.body // 取响应的data字段传给res.send res.send((await getData(route)).data) })
额外优化建议
建议加上错误捕获逻辑,避免第三方接口请求失败时抛出未处理的Promise异常:
app.post('/api', async (req, res) => { try { let { route } = req.body res.send((await getData(route)).data) } catch (err) { res.status(500).send({ code: 500, msg: '接口请求失败', error: err.message }) } })
内容的提问来源于stack exchange,提问作者gibbers
相关产品推荐
相关产品推荐

