Node.js API服务端正常返回数据 React客户端及Postman调用返回空数组
问题根因
你的问题核心是跨请求场景下签名Cookie未正确携带,导致req.signedCookies.name为undefined,最终执行的SQL语句实际为select * from new_schema.images where username = 'undefined',无匹配数据所以返回空数组。
浏览器直接访问能正常返回,是因为你之前在同域下完成过登录认证,浏览器自动携带了有效的签名Cookie。
排查步骤&解决方案
1. 先验证根因
在/files接口逻辑最开头增加日志,确认调用时是否能正常获取到Cookie值:
app.get('/files', (req, res) => { console.log('当前获取的签名Cookie name:', req.signedCookies.name) // 原有逻辑 })
如果日志输出为undefined,即可确认是Cookie携带问题。
2. 修正服务端CORS配置
默认的cors()配置不允许跨域请求携带凭证,需要修改为允许携带Cookie的配置:
// 替换原来的app.use(cors()) app.use(cors({ origin: process.env.NODE_ENV === 'production' ? '你的生产前端域名' : 'http://localhost:3000', // 也可以填true表示允许所有请求源,生产环境建议明确指定 credentials: true // 核心配置:允许跨域请求携带Cookie }))
3. 修正React端Axios配置
跨域请求要携带Cookie,需要Axios开启withCredentials配置:
// 全局配置(推荐) axios.defaults.withCredentials = true // 或者单次请求单独配置 axios.get('http://你的服务端地址/files', { withCredentials: true })
4. Postman调用适配
Postman不会自动携带认证Cookie,需要先调用/authenticate接口完成登录,Postman会自动保存返回的Cookie,后续再调用/files即可正常携带。
5. 补充接口容错逻辑
避免未登录请求导致异常SQL执行,增加登录校验:
app.get('/files', (req, res) => { const username = req.signedCookies.name if (!username) { return res.status(401).send({ msg: '未完成身份认证,请先登录' }) } const sql = `select * from new_schema.images where username = ` + mysql.escape(username) db.query(sql, (err, results) => { if (err) { throw err } res.send(results) }) })
6. 生产环境Cookie适配
如果是生产环境前后端跨域部署,需要给Cookie增加适配浏览器SameSite策略的配置,修改/authenticate接口的Cookie配置:
const options = { httpOnly: true, signed: true, sameSite: process.env.NODE_ENV === 'production' ? 'none' : 'lax', secure: process.env.NODE_ENV === 'production' };
内容的提问来源于stack exchange,提问作者Karthikeyan M
相关产品推荐
相关产品推荐

