React生产部署时需用Nginx反向代理区分/api请求与前端路由:/api/开头的请求透传至后端(如http://127.0.0.1:8080),其余请求交由index.html处理;须用^~ /api/确保前缀匹配优先级,proxy_pass末尾加/以剥离路径前缀,并配置超时与请求头。
React 应用部署到生产环境后,前端通过相对路径(如
)调用后端 API,但浏览器实际发起的是对当前域名的请求(比如
),而该地址往往并未配置后端服务——这会导致 404 或连接超时。根本原因不是网络问题,而是前端路由与后端 API 路由未被 Nginx 正确区分和转发。解决的关键在于:**用 Nginx 做反向代理,把所有以
开头的请求透传给真实后端,其余请求全部交给 React 的
处理(支持前端路由)**。
正确配置 Nginx location 分流规则
Nginx 必须明确区分静态资源、API 接口和前端路由。不能只靠
一把抓,否则所有请求(包括
)都会落到
,导致前端发不出真实 API 请求。
推荐配置示例(假设后端运行在
):
}
使用而非
:确保前缀匹配优先级高于正则 location,防止被其他规则覆盖
末尾带
:Nginx 会自动剥离
前缀再转发,后端收到的是
而非
;若不加斜杠,路径会原样透传,易出错
显式设置超时时间
:默认
是 60 秒,但某些长耗时接口或弱网环境仍可能触发超时,按需调大
确认 React 请求路径与 Nginx 规则一致
前端代码中 API 请求必须使用相对路径,且严格匹配 Nginx 中定义的代理前缀。
✅ 正确写法:
、
❌ 错误写法:
(硬编码开发地址,上线必失败)
❌ 错误写法:
(Nginx 没配
,直接 404)
建议统一通过环境变量控制 base URL,例如在
中设
,请求时拼接:
,便于多环境切换。
排查常见超时诱因
即使配置正确,仍可能因以下原因出现“连接超时”(Connection timed out)或“网关超时”(504 Gateway Timeout):
后端服务未启动或监听地址不对
:检查
,确认后端确实在
监听(而非仅
或
但防火墙拦截)
Docker 容器网络隔离
:若后端在 Docker 中,Nginx 在宿主机,
无法访问容器内服务,应改用
(Mac/Windows)或宿主机真实 IP(Linux)
SELinux 或防火墙拦截
:CentOS/RHEL 默认开启 SELinux,可能阻止 Nginx 建立 outbound 连接,执行
临时放行
后端自身响应慢
:用
直连后端测试耗时,排除后端性能瓶颈
验证与调试技巧
快速确认是否生效:
浏览器访问
,应返回后端响应(非 HTML 页面);若返回首页内容,说明 location 未命中,检查 Nginx 配置语法和重载状态(
)
查看 Nginx error log:
,关注
或
等关键词
在
块中临时加
,访问
看是否返回该字符串,验证路由是否走对
/api/usershttps://your-app.com/api/users/api/index.htmltry_files $uri $uri/ /index.html;/api/loginindex.htmlhttp://127.0.0.1:8080
location / {
try_files $uri $uri/ /index.html;
}
location ^~ /api/ {
proxy_pass https://www.php.cn/link/2c98005815b8652f236d1be11039c4bc;
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;
# 关键:避免因后端响应慢或网络抖动导致超时
proxy_connect_timeout 60;
proxy_send_timeout 60;
proxy_read_timeout 60;
^~ /api//api/proxy_pass//api//users/api/usersproxy_read_timeoutfetch('/api/users')axios.get('/api/orders')fetch('http://localhost:8080/api/users')fetch('/backend/api/users')/backend/.env.productionREACT_APP_API_BASE_URL=/apifetch(`${process.env.REACT_APP_API_BASE_URL}/users`)netstat -tuln | grep :8080127.0.0.1:8080localhost0.0.0.0proxy_pass http://127.0.0.1:8080http://host.docker.internal:8080setsebool -P httpd_can_network_connect 1curl -v https://www.php.cn/link/2c98005815b8652f236d1be11039c4bcapi/testhttps://your-app.com/api/healthnginx -t && nginx -s reloadtail -f /var/log/nginx/error.logupstream timed outconnection refusedlocation ^~ /api/return 200 "proxy hit";/api/test