我希望弄清楚为什么在 Firefox 中运行的 React 应用程序中的 API 请求失败。
标题如下:
Accept */*
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Connection keep-alive
DNT 1
Host backend:8080
origin http://localhost:3000
Referer http://localhost:3000/
User-Agent Mozilla/5.0 ...
在 Chrome 上,一条不透明的消息表明某种网络(ish)错误:
request.js?176a:41 GET http://backend:8080/api/foobar/
net::ERR_NAME_NOT_RESOLVED
在 Firefox 上,似乎还有更多信息:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://backend:8080/api/foobar/. (Reason: CORS request did not succeed).
我有一个由两个相关节点组成的环境,
frontend
和 backend
。 frontend
正在运行一个托管 React frontend
位的服务器。 backend
是一个 Flask 应用程序,提供一组简单的 JSON API。目的是让 frontend
通过 JSON API 调用 backend
。docker-compose
配置使得它们运行在同一个逻辑网络上。起初,我怀疑是 docker-compose
问题,也可能是 DNS 故障。但是,我可以通过手动停止 frontend
节点并手动将同一个容器重新附加到网络来排除这种情况,这样我就可以运行 bash
shell 并 ping backend
主机。此外,我能够通过 curl
从 backend
获取相同的位。所以这排除了它是 Docker 网络问题(我认为)。下一个合乎逻辑的罪魁祸首与 CORS 有关。
frontend
请求正在访问一个不同的域(例如 backend
),因此这可以解释该行为。在 docs listed in the dev console of Firefox 之后,声称发生了“某种基本网络错误”。
为了更好地衡量,我在
backend
上设置了 Flask-CORS 并验证了正确的 header 正在从服务器中继。准确地说,是 Access-Control-Allow-Origin: *
。然而,从
backend
服务器的日志来看,仍然没有新的网络请求被发出。我推测,根据 Mozilla CORS Docs 中描述的特殊情况,可能有一个 OPTION
请求被触发到 backend
,并且失败了。然而,这至少会在 Flask 控制台输出中触发一个日志条目,指示 OPTION
请求被触发。为了放纵我的偏执狂,我什至爆发了 Wireshark。 Firefox(或 Chrome)甚至似乎都没有发出任何相关的网络请求!很可能我把这件事复杂化了,这是一件非常简单的事情。但是会喜欢一些指向正确方向的指针。
最佳答案
TLDR - JavaScript 在浏览器中运行(后端开发人员说)frontend
上引用的主机应该是 localhost
,因为 backend
端口通过 Docker 暴露在 localhost
上。 frontend
代码在浏览器中运行(而不是专门在容器中)。容器只是一个提供这些位的过程。
不透明的网络错误可能是由于引用了主机网络不存在的域名所致。因为它是 docker-compose
虚拟网络的一部分。
关于reactjs - CORS 请求在 docker-compose 环境中失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53422421/