我希望弄清楚为什么在 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).

我有一个由两个相关节点组成的环境, frontendbackendfrontend 正在运行一个托管 React frontend 位的服务器。 backend 是一个 Flask 应用程序,提供一组简单的 JSON API。目的是让 frontend 通过 JSON API 调用 backend
docker-compose 配置使得它们运行在同一个逻辑网络上。起初,我怀疑是 docker-compose 问题,也可能是 DNS 故障。但是,我可以通过手动停止 frontend 节点并手动将同一个容器重新附加到网络来排除这种情况,这样我就可以运行 bash shell 并 ping backend 主机。此外,我能够通过 curlbackend 获取相同的位。所以这排除了它是 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)甚至似乎都没有发出任何相关的网络请求!

很可能我把这件事复杂化了,这是一件非常简单的事情。但是会喜欢一些指向正确方向的指针。

最佳答案

reactjs - CORS 请求在 docker-compose 环境中失败-LMLPHP

TLDR - JavaScript 在浏览器中运行(后端开发人员说)
frontend 上引用的主机应该是 localhost,因为 backend 端口通过 Docker 暴露在 localhost 上。 frontend 代码在浏览器中运行(而不是专门在容器中)。容器只是一个提供这些位的过程。

不透明的网络错误可能是由于引用了主机网络不存在的域名所致。因为它是 docker-compose 虚拟网络的一部分。

关于reactjs - CORS 请求在 docker-compose 环境中失败,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53422421/

10-12 18:48