当前端和后端位于虚拟 Docker 网络中时,如何使用 axios 寻址后端主机
Posted
技术标签:
【中文标题】当前端和后端位于虚拟 Docker 网络中时,如何使用 axios 寻址后端主机【英文标题】:How to address backend host with axios, when frontend and backend are in virtual docker network 【发布时间】:2019-10-15 21:55:05 【问题描述】:我正在构建一个简单的登录网站,我的 vue-frontend 需要从连接到 sql 数据库的 nodejs-backend 检索用户数据。 我决定为此使用 docker-compose,据我了解,docker-compose 会自动为我的 docker-compose.yml 中提到的服务设置网络。
似乎不起作用的是我在代码中处理后端的方式。 我怀疑这可能是因为我使用 axios 向我的后端发送请求的方式。
我已经检查了默认的 docker-network 并且能够使用我在网络配置中找到的 dns 名称从我的前端 ping 到我的后端。 但是在我的代码中使用相同的名称不起作用。
有效的方法是将主机端口映射到我公开的 api 端口并使用http://localhost:5000 作为地址,但这违背了 docker 网络的目的。
我的 docker-compose.yml:
version: '3.3'
services:
vue-frontend:
image: flowmotion/vue-js-frontend
ports:
- 8070:80
depends_on:
- db-user-api
db-user-api:
image: flowmotion/user-db-api
environment:
- PORT=5000
ports:
- 5000:5000 #only needed if docker network connection can't be established
有问题的 Vue-fontend 文件:
登录.vue
methods:
async login()
try
const response = await authenticationService.login(
email: this.email,
password: this.password
);
this.$store.dispatch("setToken", response.data.token);
this.$store.dispatch("setUser", response.data.user);
this.$router.push( path: "/" );
catch (error)
this.showError = true;
this.error = error.response.data.error;
;
</script>
authenticationService.js
import api from "@/services/api";
export default
login(credentials)
return api().post("login", credentials);
;
api.js
import axios from 'axios';
import config from '../config/config';
export default () =>
return axios.create(
baseURL: config.userBackendServer
);
;
config.js()
module.exports =
userBackendServer: 'http://cl-dashboard_db-user-api_1:5000' //this doesn't seem to work
;
//using 'http://localhost:5000' works if ports are mapped to host machine.
预期结果将是我的后端进行 sql 查找。
实际结果是,我的前端没有连接到我的后端,而是给了我一个 404 状态并且我的后端永远无法到达
【问题讨论】:
【参考方案1】:你是正确的假设 docker 网络中的容器可以在不向外部世界开放任何端口的情况下相互通信。
要点是-您的 vue 应用程序不在任何容器中-它作为 js 脚本文件从容器提供给您的浏览器,它是将请求发送到您的节点后端的那个。因为您的浏览器无论如何都不在 docker 网络内 - 您必须使用外部端口映射(在您的情况下为 localhost:5000
)才能到达后端。
如果您对此还有任何疑问,请告诉我。
【讨论】:
好的,这是有道理的。因此,对于部署,我是否需要使用 docker-compose.yml 中指定的端口指定服务 ip 地址/URI?像这样: userBackendServer: 'URItoMyApp:5000' 把它作为环境变量放在你的.env
文件中,在vue应用根目录下。现在它将是VUE_APP_API_ROOT=http://localhost:500/
,并在生产中将其更改为您的服务器主机名。您的后端生产容器应该映射到主机默认端口(80 和 443),因此您不需要指定任何端口号。
@hudac 正确,CORS 标头不应在生产中使用。通常的架构会放置一个代理服务器(比如 nginx)来为前端文件提供服务,并将/api/*
请求重定向到后端服务器。例如:cli.vuejs.org/guide/deployment.html#docker-nginx
好的,我找到了这个例子 github.com/wkrzywiec/kanban-board/blob/master/kanban-ui/… - nginx 反向代理,它在内部重定向 /api/* 的调用。谢谢!
@Vivere 在生产中,您通常会使用代理来实现前端和后端的相同域名(否则您将面临 CORS),因此您可以从请求的 URL 中删除主机名,默认情况下浏览器将使用前端域名作为主机名(例如,您将 AJAX 发送到“/api/image1.png”),不带主机名。以上是关于当前端和后端位于虚拟 Docker 网络中时,如何使用 axios 寻址后端主机的主要内容,如果未能解决你的问题,请参考以下文章