生产环境下React应用如何代理API请求到独立Express服务器
React + Express 生产环境代理失效最优解决方案
create-react-app 内置的proxy配置仅作用于本地开发服务器,生产构建后不存在对应的转发服务因此会失效,最优方案通过环境变量自动区分+统一请求封装实现,无需手动修改业务代码前缀,也不会出现地址拼接错误问题。
第一步:配置React端环境变量
Create React App 原生支持读取REACT_APP_开头的自定义环境变量,可在项目根目录新增两个环境配置文件自动适配不同环境:
- 开发环境配置文件
.env.development:REACT_APP_API_BASE_URL = /api - 生产环境配置文件
.env.production:REACT_APP_API_BASE_URL = https://你的Express服务Heroku完整地址/api
注意:修改环境变量后需要重启React开发服务才会生效。
第二步:封装统一请求实例
避免在业务代码中手动拼接地址,统一封装请求实例自动绑定基础前缀,以常用的axios为例:
import axios from 'axios' // 初始化请求实例,自动读取对应环境的接口前缀 const apiClient = axios.create({ baseURL: process.env.REACT_APP_API_BASE_URL, timeout: 10000 }) // 后续所有业务请求均通过该实例发起,无需手动加前缀 // 示例:发起/users请求,会自动根据环境拼接完整前缀 export const getUsers = () => apiClient.get('/users')
你之前遇到的客户端地址拼接问题,是因为生产环境的接口地址没有写完整的
https协议头,封装实例时填写完整的服务地址即可避免该问题。
第三步:Express端接口前缀统一(可选但推荐)
为了适配开发环境的proxy规则,推荐给所有Express接口统一挂载/api前缀:
const express = require('express') const app = express() // 原有业务路由统一挂在/api前缀下,无需修改路由内部逻辑 app.use('/api', yourRouterModule)
同域部署优化方案(可选)
如果希望生产环境也和开发环境一样走同域请求、避免跨域配置,可以将React生产构建产物托管到Express服务中:
- React项目执行
npm run build得到构建产物build文件夹,将其复制到Express项目根目录 - Express添加静态资源托管逻辑,放在所有接口路由之后:
const path = require('path') // 托管React静态资源 app.use(express.static(path.join(__dirname, 'build'))) // 适配SPA前端路由的history模式 app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build', 'index.html')) })
该方案下生产环境的前端和接口运行在同一个Heroku服务下,.env.production中的REACT_APP_API_BASE_URL可直接填写/api,和开发环境完全一致。
内容的提问来源于stack exchange,提问作者joaquin31415
相关产品推荐
相关产品推荐

