求助:Nginx无法代理React前端至Flask后端的API请求
问题背景
搭建了React+Flask应用,基础服务器配置正常,但React前端内部的API调用失败。Nginx配置了两个代理规则,分别指向React(3000端口)和Flask(5001端口),外部直接访问API正常,但前端内部调用时Nginx报错。
Nginx服务器配置
server { listen 80 default_server; listen [::]:80 default_server; server_name artisan-02.myartisan.works; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; add_header X-Served-By artisan-02; } location /api/ { proxy_pass http://localhost:5001; 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; add_header X-Served-By artisan-02; } }
外部API访问验证
通过curl直接访问API可正常获取数据:
❯ curl -sL https://myartisan.works/api/v1/contractors/5 {"address":"4333 Nolan View\nMckeemouth, MN 12184","bookings":[{"booking_date":"2023-09-11T15:18:52","contract_id":null,"contractor_id":5,"id":1,"service_id":5,"status":"pending","user_id":6,"user_reviews":...}
Nginx错误日志
2023/11/16 11:33:11 [error] 13480#13480: *3005 connect() failed (111: Connection refused) while connecting to upstream, client: 174.138.92.85, server: artisan-01.myartisan.works, request: "GET /static/js/bundle.js HTTP/1.1", upstream: "http://127.0.0.1:3000/static/js/bundle.js", host: "myartisan.works" 2023/11/16 11:35:58 [error] 13480#13480: *3007 connect() failed (111: Connection refused) while connecting to upstream, client: 174.138.92.85, server: artisan-01.myartisan.works, request: "GET /api/v1/contractors HTTP/1.1", upstream: "http://127.0.0.1:5001/api/v1/contractors", host: "myartisan.works"
已尝试操作
将React应用内的请求地址从http://127.0.0.1:5001/api/v1/resource改为http://127.0.0.1:80/api/v1/resource,问题仍未解决。
解决方案
1. 检查后端服务监听地址
错误日志显示连接被拒绝,说明Nginx无法连接到127.0.0.1:3000和127.0.0.1:5001。确认React和Flask服务是否绑定到0.0.0.0而非仅127.0.0.1:
- Flask启动时指定
host=0.0.0.0:app.run(host='0.0.0.0', port=5001) - React开发服务器启动时指定
host=0.0.0.0:npm start --host 0.0.0.0
2. 修正Nginx代理路径
location /api/配置中,proxy_pass http://localhost:5001会将请求转发到http://localhost:5001/api/v1/contractors,如果Flask的API路由是从/v1/开始而非/api/v1/,会导致路径不匹配。改为proxy_pass http://localhost:5001/(注意末尾的斜杠),Nginx会去掉/api前缀后转发请求:
location /api/ { proxy_pass http://localhost:5001/; 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; add_header X-Served-By artisan-02; }
3. 调整React请求地址
前端请求应使用相对路径,避免硬编码127.0.0.1,直接写/api/v1/resource,请求会自动指向当前域名的Nginx,由Nginx代理到Flask。
4. 检查服务器块匹配问题
错误日志中请求的server是artisan-01.myartisan.works,但提供的Nginx配置是artisan-02.myartisan.works,说明请求可能被路由到了错误的服务器块。为myartisan.works单独配置服务器块:
server { listen 80; listen [::]:80; server_name myartisan.works; location / { proxy_pass http://localhost:3000; proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; add_header X-Served-By artisan-02; } location /api/ { proxy_pass http://localhost:5001/; 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; add_header X-Served-By artisan-02; } }
5. 验证服务状态
执行以下命令确认React和Flask服务是否正常运行并监听对应端口:
# 检查3000端口监听情况 ss -tulpn | grep :3000 # 检查5001端口监听情况 ss -tulpn | grep :5001
内容的提问来源于stack exchange,提问作者Habeeb Dindi

