Docker-Compose部署Vue+Node.js Express跨域连接问题求助
编辑: 查看浏览器日志后发现:预检请求响应未通过跨域检查:'Access-Control-Allow-Origin'头的值为'http://127.0.0.1:8888',与请求源不匹配。
第二次编辑: 在帖子底部补充更多信息
Vue+Node+MariaDB Docker部署异常问题
本地运行正常,但Docker容器化部署后,提交数据无任何反应,API日志中无POST请求记录,推测UI与API间存在连接异常。技术栈包含Vue.js前端、Node.js Express后端/API、MariaDB数据库,参考教程搭建(仅修改了数据库名称和变量名)。Docker启动后,服务器已成功连接MariaDB,Vue应用可正常浏览,但提交数据时无响应。
文件夹结构

核心配置文件
.env文件
MYSQLDB_USER=root MYSQLDB_ROOT_PASSWORD=root MYSQLDB_DATABASE=rgs MYSQLDB_LOCAL_PORT=3307 MYSQLDB_DOCKER_PORT=3306 NODE_LOCAL_PORT=6868 NODE_DOCKER_PORT=8080 CLIENT_ORIGIN=http://127.0.0.1:8888 CLIENT_API_BASE_URL=http://127.0.0.1:6868/api/users VUE_LOCAL_PORT=8888 VUE_DOCKER_PORT=80
compose.yaml文件
services: mariadb: image: mariadb restart: unless-stopped env_file: ./.env environment: - MYSQL_ROOT_PASSWORD=$MYSQLDB_ROOT_PASSWORD - MYSQL_DATABASE=$MYSQLDB_DATABASE ports: - $MYSQLDB_LOCAL_PORT:$MYSQLDB_DOCKER_PORT volumes: - db:/var/lib/mysql networks: - backend api: depends_on: - mariadb build: ./api restart: unless-stopped env_file: ./.env ports: - $NODE_LOCAL_PORT:$NODE_DOCKER_PORT environment: - DB_HOST=mariadb - DB_USER=$MYSQLDB_USER - DB_PASSWORD=$MYSQLDB_ROOT_PASSWORD - DB_NAME=$MYSQLDB_DATABASE - DB_PORT=$MYSQLDB_DOCKER_PORT - CLIENT_ORIGIN=$CLIENT_ORIGIN networks: - backend - frontend ui: depends_on: - api build: context: ./ui args: - VUE_APP_API_BASE_URL=$CLIENT_API_BASE_URL ports: - $VUE_LOCAL_PORT:$VUE_DOCKER_PORT networks: - frontend volumes: db: networks: backend: frontend:
http-common.js文件
import axios from "axios"; export default axios.create({ baseURL: process.env.VUE_APP_API_BASE_URL || "http://localhost:8080/api/users", headers: { "Content-type": "application/json" } });
VUE UI Dockerfile
# Stage 1 FROM node:14 as build-stage WORKDIR /ui COPY package.json . RUN npm install COPY . . ARG VUE_APP_API_BASE_URL ENV VUE_APP_API_BASE_URL=$VUE_APP_API_BASE_URL RUN npm run build # Stage 2 FROM nginx:1.17.0-alpine COPY --from=build-stage /ui/dist /usr/share/nginx/html EXPOSE $VUE_DOCKER_PORT CMD nginx -g 'daemon off;'
server Dockerfile
# syntax=docker/dockerfile:1 ARG NODE_VERSION=20.11.1 FROM node:${NODE_VERSION}-alpine ENV NODE_ENV production WORKDIR /api COPY package.json . RUN npm install COPY . . CMD npm start
server.js文件
require("dotenv").config(); const express = require("express"); const cors = require("cors"); const app = express(); var corsOptions = { origin: process.env.CLIENT_ORIGIN || "http://localhost:8081" }; app.use(cors(corsOptions)); app.use(express.json()); app.use(express.urlencoded({ extended: true })); const db = require("./app/models"); db.sequelize.sync() .then(() => { console.log("Synced db."); }) .catch((err) => { console.log("Failed to sync db: " + err.message); }); // 开发环境专用代码(已注释) /*db.sequelize.sync({ force: true }).then(() => { console.log("Drop and re-sync db."); });*/ app.get("/", (req, res) => { res.json({ message: "Welcome to rgs." }); }); require("./app/routes/user.routes.js")(app); const PORT = process.env.NODE_DOCKER_PORT || 8080; app.listen(PORT, () => { console.log(`Server is running on port ${PORT}.`); });
db.config.js文件
module.exports = { HOST: process.env.DB_HOST, USER: process.env.DB_USER, PASSWORD: process.env.DB_PASSWORD, DB: process.env.DB_NAME, port: process.env.DB_PORT, dialect: "mariadb", pool: { max: 5, min: 0, acquire: 30000, idle: 10000 } };
第二次编辑补充内容:
将CLIENT_ORIGIN=http://172.0.0.1:8888修改为CLIENT_ORIGIN=http://localhost:8888后,出现新问题:大部分页面可正常访问,但打开带输入框的页面时,触发资源未找到错误:
Failed to load resource: the server responded with a status of 404 (Not Found)
vue-router.mjs:3479 ChunkLoadError: Loading chunk 578 failed. (error: http://localhost:8888/js/578.1a9ac476.js) at t.f.j (app.6e12f49f.js:1:5420) at app.6e12f49f.js:1:2555 at Array.reduce (<anonymous>) at t.e (app.6e12f49f.js:1:2520) at component (app.6e12f49f.js:1:391) at Ue (vue-router.mjs:2101:40) at vue-router.mjs:3309:22
相关代码片段
App.vue(部分)
<script setup> import HeaderLogin from '@/components/AllSitesHeaderLogin.vue' import HeaderLoggedIn from '@/components/AllSitesHeaderLoggedIn.vue' ... </script> <template> <!-- <div v-if="!loggedIn"> --> <div v-if="true"> <HeaderLogin></HeaderLogin> </div>
AllSitesHeaderLogin.vue
<template> <header> <nav> <router-link to="/">Home</router-link> | <router-link to="/forum">Forum</router-link> | <router-link to="/add">Login</router-link> </nav> </header> </template> <script> export default { name: 'AllSitesHeaderLogin', } </script>
router.js
import { createWebHistory, createRouter } from "vue-router"; const routes = [ { path: '/:pathMatch(.*)*', component: () => import("./views/HomeView.vue") }, { path: "/", alias: "/home", name: "home", component: () => import("./views/HomeView.vue") }, { path: "/login", name: "login", component: () => import("./views/LoginView.vue") }, { path: "/add", name: "add", component: () => import("./views/RegisterView.vue") }, { path: "/about", name: "about", component: () => import("./views/AboutView.vue") } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
内容的提问来源于stack exchange,提问作者hellodarkness
相关产品推荐
相关产品推荐

