React 代理错误:无法将请求 /api/ 从 localhost:3000 代理到 http://localhost:8000 (ECONNREFUSED)
Posted
技术标签:
【中文标题】React 代理错误:无法将请求 /api/ 从 localhost:3000 代理到 http://localhost:8000 (ECONNREFUSED)【英文标题】:React Proxy error: Could not proxy request /api/ from localhost:3000 to http://localhost:8000 (ECONNREFUSED) 【发布时间】:2018-10-10 23:31:09 【问题描述】:我有一个使用 jwt 向 Django 后端进行身份验证的 React 前端。后端工作正常,使用 django 视图连接得很好,但是当我尝试代理来自 React 的请求时,它给了我一个 Connection Refused 错误。
代理错误:无法将请求 /api/auth/token/obtain/ 从 localhost:3000 代理到 http://localhost:8000 (ECONNREFUSED)。
连接到http://localhost:8000/api/auth/token/obtain/ 工作正常。而且用axios发送POST请求也能正常工作,返回token json。但是当我用节点代理它时,它不起作用。
在我的package.json
我有:
"proxy":
"/api/*":
"target": "http://localhost:8000"
,
编辑:Public repo。如果您安装了 docker,您可以轻松运行。 (使用 1 个图像和 2 个容器)。克隆后只需运行docker-compose build
,然后运行docker-compose up
。
Edit2:请求标头:
*General*
Request URL: http://localhost:3000/api/auth/token/obtain/
Request Method: POST
Status Code: 500 Internal Server Error
Remote Address: [::1]:3000
Referrer Policy: no-referrer-when-downgrade
*Response Headers*
HTTP/1.1 500 Internal Server Error
X-Powered-By: Express
Date: Mon, 30 Apr 2018 21:23:17 GMT
Connection: keep-alive
Transfer-Encoding: chunked
*Request Headers
POST /api/auth/token/obtain/ HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Content-Length: 45
Pragma: no-cache
Cache-Control: no-cache
Origin: http://localhost:3000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_4) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/65.0.3325.181 Safari/537.36
Content-Type: application/json
Accept: */*
Referer: http://localhost:3000/login
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9,fr;q=0.8,ja;q=0.7
【问题讨论】:
如果您发布您的 Django 和 Node 代码会很有帮助。 @MattMorgan 对不起。已添加。 不确定,无法快速在本地运行。 CRA 文档表明您的target
模式可能是错误的。您是否尝试过:"/api"
而不是 "/api/*"
...想知道它是否在尝试匹配 api/only-one-more-element
@MattMorgan 不适用于 /api
、/api/
或 /api/*
,或仅适用于 "proxy":"http://localhost:8000"
。
【参考方案1】:
所以问题是因为 Node 开发环境和 Django 开发环境都在单独的 docker 容器中运行,所以 localhost
指的是节点容器,而不是桥接网络。
所以关键是使用容器链接,这些链接是在使用docker-compose
时自动创建的,并将其用作主机名。所以我把它改成了
"proxy":
"/api":
"target": "http://django:8000"
,
只要您使用相同的docker-compose
命令启动两个容器,这就会奏效,否则您必须在docker-compose.yml
文件中手动指定 external_links。
【讨论】:
我遇到了同样的问题,对我来说,当 package.json 中的代理是一个对象时出现错误,所以它必须是一个字符串,但http://<container-name>:<port>
工作得很好!非常感谢【参考方案2】:
我也遇到了同样的问题。大多数搜索结果都提到将"secure": false
或"ignorePath": true
添加到您的代理配置中。像这样的:
"proxy":
"/api/*":
"target": "http://localhost:8000",
"secure": false
,
可能值得一试,但不幸的是,这些都不适合我。虽然每个地址(http://localhost:3000 和 http://localhost:8000)在浏览器中都可以正常工作,但可能因为容器实际上是代理它需要使用 Docker 地址?
编辑--
好吧,我想我明白了。我相信它确实与容器到容器的通信有关。查看您的docker-compose
,您的api 服务器称为django
。将您的 package.json 文件更改为:
"proxy":
"/api/*":
"target": "http://django:8000",
"secure": false
【讨论】:
我昨天确实修复了这个问题,并发布了我如何修复它的答案。对我来说,这是因为两台服务器运行在不同的节点容器上,所以localhost
并没有指代与 django 相同的主机。
这个答案极大地帮助我解决了今天的问题,非常感谢@VincentJr【参考方案3】:
我遇到了类似的问题,但在 Mac 机器上。我在 package.json 中将localhost
更改为127.0.0.1
,这对我有用,如下所示:
"proxy": "http://127.0.0.1:5000"
【讨论】:
试过了,还是不行。 React 仍在尝试向 localhost:3000 发送请求【参考方案4】:如果您使用的是较新版本的 CRA 2.0+,则需要通过手动代理执行此操作。 https://facebook.github.io/create-react-app/docs/proxying-api-requests-in-development#configuring-the-proxy-manually
【讨论】:
【参考方案5】:如果您不想设置 docker compose,也可以使用 docker 网络:
创建网络并在该网络中运行 docker 容器
docker network create webapp_network
docker run -d -p 5000:5000 --name webapp_backend --network webapp_network webapp_backend_image
docker run -d -p 3000:3000 --name webapp_frontend --network webapp_network webapp_frontend_image
在我的前端 React webapp 的 package.json 中添加了一行:
"proxy": "http://webapp_backend:5000"
请注意,您现在可以使用容器名称而不是 localhost 来引用您的后端
【讨论】:
【参考方案6】:昨天将Docker
升级到版本v19.03.13
(在Mac
上)后可以看到错误,重新启动Docker
解决了这个问题。该应用程序还运行Node.js
/React
,但不是Django
。基本上,我在连接到MongoDB Atlas
时遇到了与身份验证/从云数据库中获取任何内容相关的问题。
【讨论】:
【参考方案7】:正确答案是使用手动代理和
-
目标=码头地址
django:4000
正确的主机头localhost:8000
因为如果 Django 使用返回绝对 url 的reverse
函数
reverse('preview-mail', args=[mail.pk],request=request)
您需要为其设置正确的 HOST 标头,否则您可能会得到类似的结果 URL https://django:4000/your-url`
const proxy = require('http-proxy-middleware');
module.exports = function(app)
app.use(
proxy('/api',
target: 'http://django:4000',
changeOrigin: true,
secure: false,
pathRewrite:
'^/api': ''
,
onProxyReq: function (proxyReq, req, res)
proxyReq.setHeader("host", 'localhost:8000')
)
)
【讨论】:
【参考方案8】:为 localhost 选择 exact 值来填充“目标”属性主要是解决方案(它可以是 localhost, 127.0.0.1, [::1] )。
mac 用户应该输入终端来获取解决方案:
sudo lsof -iTCP -sTCP:LISTEN -n -P
【讨论】:
【参考方案9】:如果您正在开发 MERN 堆栈应用程序,请确保您不在客户端文件夹中。你需要在根目录下。在根目录下,在终端中运行此命令。 npm run start:dev
【讨论】:
太棒了。谢谢你。我忘了我在我的应用程序的客户端文件夹中......?以上是关于React 代理错误:无法将请求 /api/ 从 localhost:3000 代理到 http://localhost:8000 (ECONNREFUSED)的主要内容,如果未能解决你的问题,请参考以下文章
无法将来自 localhost:3000 的请求代理到 localhost:7000 ReactJs