React+Nginx部署后调用localhost接口遭拒绝的问题排查
问题
在远程Ubuntu服务器上部署了React前端、Django REST后端,并用Nginx做反向代理管理,conf.d/bookmarks.conf的配置如下:
server { listen 80; listen [::]:80; location /api/ { # Backend proxy_pass http://127.0.0.1:1337/api/; } location / { # Frontend root /var/www/bookmarks/html/; index index.html; try_files $uri $uri/ /index.html; } }
通过python manage.py runserver 127.0.0.1:1337启动Django应用,React静态文件已放置在配置指定的目录中。
尝试在React中调用API的代码如下:
const generateOpendIdLink = async () => { const generateOpendIdLinkEndpoint = 'http://127.0.0.1/api/opendid-link-generator/'; const requestOptions = { method: 'GET', headers: {'Content-Type': 'application/json'}, }; try { const response = await fetch(generateOpendIdLinkEndpoint, requestOptions); if (response.status == 200) { ... }; } catch (error) { console.log(error); }; };
但出现错误:
GET http://127.0.0.1/api/opendid-link-generator/ net::ERR_CONNECTION_REFUSED
奇怪的是,用Postman访问服务器IP地址http://XX.XXX.XX.XX/api/opendid-link-generator/可正常调用API,将React代码中的127.0.0.1替换为服务器IP后也能正常工作。已经将Django的ALLOWED_HOSTS = ['*']用于测试,但问题仍未解决,请问问题根源是什么?
问题根源
核心问题是前端代码里写的127.0.0.1是相对于用户的本地浏览器,而非远程服务器:
- 当浏览器加载React代码后,执行
fetch('http://127.0.0.1/api/...')时,会尝试连接浏览器所在本地机器的127.0.0.1端口,但你的Django后端是部署在远程服务器上的,本地机器并没有运行Django服务,因此会出现连接拒绝的错误。 - Postman能正常访问是因为它直接向远程服务器IP发起请求;把React代码里的地址换成服务器IP后正常,是因为此时浏览器请求的是远程服务器地址,请求经过Nginx反向代理后转发到服务器本地的127.0.0.1:1337。
推荐解决方法
- 使用相对路径调用API:把API地址改成相对路径
/api/opendid-link-generator/,这样浏览器会自动使用当前页面的域名(服务器IP或绑定的域名)发起请求,自动匹配Nginx的反向代理配置:
const generateOpendIdLinkEndpoint = '/api/opendid-link-generator/';
- 通过环境变量管理API地址:在React项目中配置环境变量统一管理API基础地址,比如在
.env文件中添加:
REACT_APP_API_BASE_URL=/api/
然后在代码中引用:
const generateOpendIdLinkEndpoint = `${process.env.REACT_APP_API_BASE_URL}opendid-link-generator/`;
这种方式更灵活,方便在开发、生产等不同环境切换API地址。
内容的提问来源于stack exchange,提问作者Oleg Blanutsa
相关产品推荐
相关产品推荐

