React对接Stripe支付时res.json未返回数据 取值为undefined
问题说明
开发搭载Node.js后端的React应用时,接入Stripe支付流程出现异常:后端生成Stripe支付会话的跳转URL逻辑验证正常,但前端接收接口响应时始终无法拿到返回的URL字段,打印结果为undefined,同项目此前res.json的响应写法可正常运行。
涉及的后端路由代码如下:
router.post("/payment", async(req, res) => { const course = await Courses.findByPk(req.body.items[0].id); const storeItems = new Map([ [course.id, { priceInCents: course.price, name: course.title }], ]) try { const session = await stripe.checkout.sessions.create({ payment_method_types: ['card'], mode: 'payment', line_items: req.body.items.map(item => { const storeItem = storeItems.get(item.id) return { price_data: { currency: "usd", product_data: { name: storeItem.name, }, unit_amount: storeItem.priceInCents, }, quantity: item.quantity, } }), success_url: 'http://localhost:3000/profile-page', cancel_url: `http://localhost:3000/course-details/${course.id}` }) res.json({ url: session.url }); } catch (e) { res.status(500).json({ error: e.message }); } });
涉及的前端请求代码如下:
if (response.data.error) { alert(response.data.error); } else { axios.post("http://localhost:3001/users_courses/payment", { items: [ { id: data.id, quantity: 1 }, ], }, { headers: { accessToken: localStorage.getItem("accessToken"), }, }).then(res => { if(res.ok) return res.json(); return res.json().then(json => Promise.reject(json)); }).then (( { url }) => { window.location.href = url; console.log(url + " this is the url"); }).catch(e => { console.error(e.error); }) }
问题根因
前端代码混用了原生Fetch API和Axios的响应处理逻辑:
- 代码里判断
res.ok、调用res.json()的写法是原生Fetch的标准用法,Axios返回的响应对象不存在ok属性,也没有挂载json()方法,这部分逻辑执行时会直接抛出异常,无法正常解析响应内容 - Axios默认会自动将接口返回的JSON响应解析为JS对象,解析后的结果存放在响应对象的
data字段中,不需要手动调用json()方法做二次解析 - 原有catch逻辑也存在问题:Axios抛出的错误对象不会直接挂载后端返回的
error字段,错误响应内容存放在e.response.data路径下
修复方案
将前端请求的响应处理逻辑替换为符合Axios规范的写法即可:
if (response.data.error) { alert(response.data.error); } else { axios.post( "http://localhost:3001/users_courses/payment", { items: [{ id: data.id, quantity: 1 }], }, { headers: { accessToken: localStorage.getItem("accessToken"), }, } ).then(res => { // 直接从res.data中取解析好的响应字段 const { url } = res.data; window.location.href = url; console.log(url + " this is the url"); }).catch(e => { // 兼容读取后端返回的错误信息 console.error(e.response?.data?.error || e.message); }) }
补充排查项
如果替换代码后仍存在异常,可按以下顺序排查:
- 确认后端已配置CORS中间件,允许前端
http://localhost:3000来源的跨域请求,同时放通自定义请求头accessToken - 确认
/payment路由前的鉴权等中间件没有提前拦截请求、提前返回响应,导致路由内的res.json({ url: session.url })逻辑不生效 - 打开浏览器开发者工具的Network面板,找到对应payment请求,查看响应详情,确认后端实际返回的HTTP状态码和响应体内容符合预期
内容的提问来源于stack exchange,提问作者Victor
相关产品推荐
相关产品推荐

