同一Docker容器内React无法从NodeJS服务器获取数据求助
部署NodeJS服务端与React+Vite客户端时的连接问题
服务端(NodeJS)配置
已启用CORS并配置单个接口,Dockerfile暴露5454端口,Docker-Compose映射端口5454:5454。
服务端代码片段:
// 启用CORS app.use(cors()); app.get("/api/listings/:city/:district/:bedrooms", (req, res) => { // 业务逻辑 });
Docker-Compose配置片段:
server: build: ./server container_name: server_c ports: - "5454:5454" expose: - 5454
客户端(React+Vite)配置
通过axios调用服务端接口,代码片段:
const URL = "https://server:5454"; useEffect(() => { setIsLoading(true); let endpoint = `${URL}/api/listings/${city}/${district}/${bedrooms}`; console.log(`Fetching data from ${endpoint}`); axios .get(endpoint) .then((res) => { console.log("Received data:", res.data); setMedianPrice(res.data.medianPrice); setAveragePrice(res.data.averagePrice); setNumberOfListings(res.data.numberOfListings); setIsLoading(false); }) .catch((error) => { console.error("An error occurred while fetching the data:", error); }); }, [city, district, bedrooms]);
问题现象
本地运行及本地容器环境均正常,容器内用curl可正常获取数据,但部署到远程服务器后客户端出现Failed to load resource: net::ERR_CONNECTION_REFUSED错误。
已尝试的排查措施
- 修改客户端接口URL:
- 使用
https://localhost:5454,报错相同 - 使用服务器公网IP的HTTPS地址,出现
net::ERR_SSL_PROTOCOL_ERROR - 使用服务器公网IP的HTTP地址,触发浏览器混合内容拦截
- 使用
- 更新服务端CORS配置为允许所有来源
补充信息
线上客户端可正常访问:https://binas.kawaiier.dev,SSL配置正常。
解决方案
修正客户端接口地址
- 客户端代码中
https://server:5454是Docker内部服务名,仅容器内网可解析,外部浏览器无法识别,需替换为服务器公网域名+反向代理路径(或正确的公网可访问地址)。 - 建议在Vite中配置环境变量,通过
.env文件管理接口地址:
客户端代码中使用:# .env.production VITE_API_BASE_URL="https://binas.kawaiier.dev/api"const URL = import.meta.env.VITE_API_BASE_URL; let endpoint = `${URL}/listings/${city}/${district}/${bedrooms}`;
- 客户端代码中
配置Nginx反向代理(关键)
服务端5454端口未配置SSL,直接公网访问会触发混合内容或SSL错误,需用Nginx将HTTPS请求反向代理到服务端容器的5454端口:server { listen 443 ssl; server_name binas.kawaiier.dev; # SSL证书配置(已有正常配置可忽略) ssl_certificate /path/to/your/cert.pem; ssl_certificate_key /path/to/your/key.pem; # 反向代理API请求到服务端容器 location /api/ { proxy_pass http://server_c:5454/api/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } # 客户端静态文件配置 location / { root /path/to/react/build; try_files $uri $uri/ /index.html; } }客户端通过同域名的
/api路径请求,既避免混合内容问题,也无需处理跨域(同源策略)。调整Docker-Compose网络(可选)
确保Nginx容器与服务端容器在同一个Docker网络中,这样Nginx才能通过server_c容器名访问服务端。可显式配置:version: '3.8' networks: app-network: driver: bridge services: server: build: ./server container_name: server_c networks: - app-network # 无需暴露5454到公网,仅容器内网访问即可 # ports: # - "5454:5454" expose: - 5454 nginx: image: nginx:alpine container_name: nginx_c networks: - app-network ports: - "443:443" - "80:80" volumes: - ./nginx/conf.d:/etc/nginx/conf.d - ./client/dist:/usr/share/nginx/html验证服务端CORS配置(可选)
若仍存在跨域问题,可显式配置CORS允许客户端域名:app.use(cors({ origin: "https://binas.kawaiier.dev", credentials: true }));
内容的提问来源于stack exchange,提问作者Serge
相关产品推荐
相关产品推荐

