React生产环境下将请求代理至外部REST API的配置问题
生产环境代理配置方案及问题排查
首先明确一个关键:你本地用的setupProxy.js或者package.json里的proxy配置,只在webpack开发服务器生效,生产环境打包成静态文件后,这些配置完全没用。生产环境的代理必须靠部署静态文件的服务器(比如Nginx)或者后端服务来实现。
生产环境实现website.com/api/request代理到api.website.com/request的方法
1. Nginx(最常用的方案)
如果用Nginx托管你的React静态文件,修改Nginx配置文件,添加对应的location规则:
server { listen 80; server_name website.com; # 指向React打包后的build文件夹 root /your/react/build/path; index index.html; # 处理/api开头的请求 location /api/ { # 把/api/后面的路径直接转发到api.website.com proxy_pass https://api.website.com/; # 传递必要的请求头,避免后端识别异常 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; } # 单页应用必备:刷新页面时路由 fallback 到index.html location / { try_files $uri $uri/ /index.html; } }
注意proxy_pass末尾的斜杠,它会自动把/api/后面的路径拼接过去,刚好满足你要的website.com/api/request转api.website.com/request的需求。
2. Node.js Express后端
如果你的项目用Express做静态文件服务器,同时处理代理,先装http-proxy-middleware,然后这么写:
const express = require('express'); const path = require('path'); const { createProxyMiddleware } = require('http-proxy-middleware'); const app = express(); // 托管React静态文件 app.use(express.static(path.join(__dirname, 'build'))); // 配置/api代理 app.use('/api', createProxyMiddleware({ target: 'https://api.website.com', pathRewrite: { '^/api': '' }, // 去掉/api前缀 changeOrigin: true, headers: { Connection: 'keep-alive' } })); // 单页应用路由 fallback app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'build', 'index.html')); }); app.listen(3000);
3. Apache
如果用Apache,在虚拟主机配置或者项目根目录的.htaccess里加这些规则:
RewriteEngine On DocumentRoot "/your/react/build/path" # 代理/api请求 RewriteRule ^api/(.*)$ https://api.website.com/$1 [P,L] # 单页应用路由 fallback RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(.*)$ /index.html [L]
记得要开启Apache的mod_rewrite、mod_proxy和mod_proxy_http模块。
你之前的配置问题分析
- 配置生效范围错了:你在
package.json和setupProxy.js里加的代理,只在本地开发时有用,生产环境根本不生效,这是核心问题。 - 路径重写的正则有差异:你本地原来的
pathRewrite是{ '^/api/': '' },后来改成了{ '^/api': '' },两者的区别是:- 原正则匹配
/api/开头,/api/request会被改成request - 新正则匹配
/api开头,/api/request会被改成/request
如果你的后端API期望的是request而不是/request,就会导致请求路径错误,返回异常数据(也就是你遇到的“数据未定义”)。
- 原正则匹配
- 本地测试建议:你直接请求
https://api.website.com/能成功,但代理不行,建议打开浏览器开发者工具,看代理后实际发送的请求URL和响应内容,和直接请求的对比下,就能知道是不是路径重写出问题了。
内容的提问来源于stack exchange,提问作者junbl
相关产品推荐
相关产品推荐

