Express后端:如何从嵌套HTTP请求向React客户端返回结果?
问题描述
我用ReactJS搭建前端、Express搭建后端,想通过向后端/paas路径发起GET请求,获取Rancher(Kubernetes)中我的namespace下所有运行中的pod列表。后端需要向Rancher API端点发起HTTPS请求,再将结果返回给前端。目前后端已成功调用Rancher API,控制台能打印数据,但不知道怎么把数据返回给前端并在浏览器控制台输出。因为预检(pre-flight)错误,无法在App.js中直接调用Rancher端点,必须通过自定义后端路由实现,求指导。
前端App.js代码
import React, { useEffect } from "react" import axios from "axios" function App() { useEffect(() => { const fecthPods = async () => { try { const response = await axios.get(`http://localhost:3001/paas`) console.log(response.data) } catch (err) { if (err.response) { // 非200范围响应 console.log(err.response.data) console.log(err.response.status) console.log(err.response.headers) } else { console.log(`Error: ${err.message}`) } } } fecthPods() },[]) return ( <div> Hello World! </div> ); } export default App;
后端原server.js代码
import express from "express" import cors from "cors" import https from "https" import bodyParser from "body-parser"; const app = express() app.use(cors()) app.use("/data", (req, res) => { res.json({ name: "Minion", favFood: "pizza"}) }) app.get("/paas", bodyParser.json(), (req, res) => { const options = { hostname: "k8.fqdn.com", port: 443, path: "/k8s/clusters/c-wwfc/v1/pods/mynamespace", method: "GET", headers: { Authorization: "Bearer token:12345" } } const request = https.get(options, (res) => { let responseBody = "" res.setEncoding("UTF-8") res.on("data", (chunk) => { console.log("---chunk", chunk.length); responseBody += chunk; }); res.on("end", () => { let json = JSON.parse(responseBody) // console.log(responseBody) console.log("Response finished"); res.json({data: responseBody}) }); }); request.end() res.json({ status: "complete", data: request.data}) }) app.listen(3001) console.log("backend up on 3001")
问题分析与修复
你的后端代码有两个核心问题:
- 变量名冲突:
https.get的回调参数用了res,和Express路由的响应对象res重名,导致回调里的res.json指向的是Rancher的响应对象,而非返回给前端的Express响应对象。 - 提前返回响应:发起Rancher请求后立刻调用
res.json({ status: "complete", data: request.data}),直接把空数据返回给前端,等Rancher响应完成后再调用res.json时,响应已经结束,会触发错误。
修改后的后端代码
import express from "express" import cors from "cors" import https from "https" const app = express() app.use(cors()) app.use(express.json()) // Express 4.16+内置了json解析,替代bodyParser.json() app.use("/data", (req, res) => { res.json({ name: "Minion", favFood: "pizza"}) }) app.get("/paas", (req, res) => { const options = { hostname: "k8.fqdn.com", port: 443, path: "/k8s/clusters/c-wwfc/v1/pods/mynamespace", method: "GET", headers: { Authorization: "Bearer token:12345" } } // 回调参数改为rancherRes,避免和Express的res冲突 const request = https.get(options, (rancherRes) => { let responseBody = "" rancherRes.setEncoding("UTF-8") rancherRes.on("data", (chunk) => { console.log("---chunk", chunk.length); responseBody += chunk; }); rancherRes.on("end", () => { console.log("Response finished"); // 用Express的res返回解析后的数据给前端 try { const podData = JSON.parse(responseBody) res.json({ data: podData }) } catch (parseErr) { res.status(500).json({ error: "解析Rancher API响应失败" }) } }); }); // 处理Rancher请求的错误 request.on("error", (err) => { console.error("获取Rancher API数据出错:", err) res.status(500).json({ error: err.message }) }) request.end() }) app.listen(3001) console.log("backend up on 3001")
说明
- 前端代码无需修改,保持原样即可。
- 修改后的后端代码解决了变量冲突问题,仅在Rancher API响应完成后才返回数据给前端,同时增加了错误处理,避免解析失败或请求出错时前端无法收到有效响应。
- 重启后端服务后,前端发起请求就能在浏览器控制台看到返回的pod数据。
内容的提问来源于stack exchange,提问作者stminion001
相关产品推荐
相关产品推荐

