🚀 Vue3+Vite 部署阿里云 OSS (Object Storage Service, 对象存储服务) 避坑指南:搞定 API (Application Programming Interface, 应用程序编程接口) 接口 404 与动态环境注入
在前后端分离的架构中,我们通常采用 “前端托管 OSS (Object Storage Service, 对象存储服务) + 后端部署 K8s (Kubernetes, 容器编排系统)” 的黄金组合。这种方案成本极低、访问速度极快。
但在将 Vue3 项目推送到阿里云 OSS (Object Storage Service, 对象存储服务) 后,我遇到了一个经典的 API (Application Programming Interface, 应用程序编程接口) 请求 404 问题。今天就来复盘一下这个从“本地跑得通”到“线上火葬场”的排查与解决过程。🛠️
📊 核心问题与解决方案速查表
| 问题现象 | 根本原因 | 解决方案 | 涉及工具/技术 |
|---|---|---|---|
| 线上 API (Application Programming Interface, 应用程序编程接口) 报 404 | 前端请求发给了 OSS (Object Storage Service, 对象存储服务) 域名,而非后端网关 IP (Internet Protocol, 互联网协议) | 注入真实网关 IP (Internet Protocol, 互联网协议) 到生产环境配置 | Shell 脚本, .env.production |
| Vite 代理失效 | server.proxy 仅在开发模式生效,构建后失效 | 修改 Axios 配置,优先读取环境变量 | Vite, Axios |
| 手动部署繁琐 | 每次需手动修改配置并拖拽上传 | 编写一键自动化部署脚本 | CLI (Command Line Interface, 命令行界面), ossutil |
| 路由不匹配 | 前端路径带 /api 但网关只认 /auth | 脚本注入时去除 /api 后缀,或修改网关 StripPrefix | Shell, Spring Cloud Gateway |
😱 问题现场:本地完美,上线 404
- 本地环境 (
npm run dev):接口访问正常,请求地址是http://localhost:3000/api/auth/...,通过 Vite 的server.proxy转发到后端,一切丝滑。 - 线上环境 (OSS (Object Storage Service, 对象存储服务)):执行 build 并上传 OSS (Object Storage Service, 对象存储服务) 后,访问域名
http://mdt.center,浏览器 Network 面板却一片爆红!🚨
请求地址变成了:
http://mdt.center/api/auth/admin/captcha❌ 404 Not Found
奇怪了,我的后端网关明明在 47.108.xx.xx,为什么浏览器还在傻傻地请求 OSS (Object Storage Service, 对象存储服务) 的域名?OSS (Object Storage Service, 对象存储服务) 里当然没有 API (Application Programming Interface, 应用程序编程接口) 接口啊!
🔍 根因分析:Vite 代理的“谎言”
经过排查,发现了两个认知误区:
- Vite 的
server.proxy仅在开发模式生效:一旦执行npm run build,生成的代码就是纯粹的 HTML (HyperText Markup Language, 超文本标记语言) / JS (JavaScript, 脚本语言) 静态文件,Vite 服务不存在了,代理配置自然也就失效了。 - Axios 配置写死:检查代码发现,Axios 的
baseURL被硬编码成了/api。
在生产环境,// ❌ 致命错误:写死了相对路径 const service = axios.create({ baseURL: '/api' })/api会被浏览器解析为当前域名 + /api,也就是去请求 OSS (Object Storage Service, 对象存储服务),导致 404。
🎯 破局思路:我们需要在打包构建(Build)的那一刻,把真实的后端网关 IP (Internet Protocol, 互联网协议) 注入到代码里,并让 Axios 读取它。
✅ 解决方案:DevOps (Development and Operations, 开发运维一体化) 脚本 + 代码改造
第一步:编写部署脚本,强制注入环境变量 💉
为了避免手动修改 .env.production 文件容易出错,我们编写一个 Shell 脚本 (deploy-web.sh)。
它在 npm run build 之前,暴力覆盖 生产环境配置文件,把网关 IP (Internet Protocol, 互联网协议) 写入 VITE_APP_BASE_API。
deploy-web.sh 内容如下:
#!/bin/bash
# ================= 🔧 配置区域 =================
# 1. 你的 OSS (Object Storage Service, 对象存储服务) Bucket 名称
BUCKET_NAME="hx-health-cloud-test"
# 2. 你的后端网关公网 IP (Internet Protocol, 互联网协议)
# ⚠️ 注意:不加 /api 后缀,直接指向网关 IP (Internet Protocol, 互联网协议)
BACKEND_API="http://xxxx"
# 3. 构建输出目录
DIST_DIR="dist"
# ==============================================
# 颜色定义
GREEN='\033[0;32m'
RED='\033[0;31m'
YELLOW='\033[1;33m'
NC='\033[0m'
echo -e "${YELLOW}🚀 开始前端自动化部署流程...${NC}"
# 0. 检查 ossutil 是否安装
if ! command -v ossutil &> /dev/null; then
echo -e "${RED}❌ 未检测到 ossutil 工具!${NC}"
echo "请先执行 brew install ossutil 安装,并运行 ossutil config 配置账号。"
exit 1
fi
# 1. 安装依赖
echo -e "${YELLOW}📦 [1/3] 检查依赖...${NC}"
# npm install --registry=https://registry.npmmirror.com
# 2. 构建项目
echo -e "${YELLOW}🏗️ [2/3] 开始构建项目 (npm run build)...${NC}"
echo "👉 注入后端 API (Application Programming Interface, 应用程序编程接口) 地址: $BACKEND_API"
# 🔥【核心差异】强烈建议用这种方式!
# 直接生成 .env.production 文件,确保 Vite 绝对能读到这个变量
cat > .env.production <<EOF
NODE_ENV=production
VITE_APP_BASE_API=$BACKEND_API
VUE_APP_BASE_API=$BACKEND_API
REACT_APP_BASE_API=$BACKEND_API
EOF
echo -e "${GREEN}✅ 环境变量文件 .env.production 已生成${NC}"
# 🚑【容错处理】临时修改 package.json 跳过 TS (TypeScript, 类型脚本语言) 类型检查
sed -i '' 's/"vue-tsc --noEmit && vite build"/"vite build"/g' package.json 2>/dev/null || sed -i 's/"vue-tsc --noEmit && vite build"/"vite build"/g' package.json
npm run build
if [ $? -ne 0 ]; then
echo -e "${RED}❌ 构建失败,请检查代码错误!${NC}"
exit 1
fi
echo -e "${GREEN}✅ 构建成功!${NC}"
# 3. 上传到 OSS (Object Storage Service, 对象存储服务)
echo -e "${YELLOW}☁️ [3/3] 正在上传到阿里云 OSS (Object Storage Service, 对象存储服务) ($BUCKET_NAME)...${NC}"
# -r: 递归上传文件夹
# -f: 强制覆盖
# --meta: 设置 Cache-Control:no-cache 确保 index.html 不被浏览器缓存,发版即生效
ossutil cp -r -f $DIST_DIR/ oss://$BUCKET_NAME/ \
--include "*" \
--meta "Cache-Control:no-cache"
if [ $? -ne 0 ]; then
echo -e "${RED}❌ 上传失败,请检查 ossutil 配置或网络!${NC}"
exit 1
fi
echo -e "${GREEN}✅ 上传成功!${NC}"
echo -e "--------------------------------------------------"
echo -e "🎉 网站已发布,请访问:"
# 这里输出你的自定义域名
echo -e "${GREEN}http://mdt.center${NC}"
echo -e "--------------------------------------------------"
第二步:改造 Axios,读取环境变量 🧬
脚本注入了变量,代码得去“读”才行。修改 src/utils/request.ts:
import axios from 'axios'
// 创建 axios 实例
const service = axios.create({
// ✅【核心修改】优先读取注入的环境变量,读不到再回退到 /api (本地开发用)
baseURL: import.meta.env.VITE_APP_BASE_API || '/api',
timeout: 15000,
headers: { 'Content-Type': 'application/json;charset=UTF-8' }
})
// ... 拦截器逻辑保持不变
🎉 最终效果
运行脚本 ./deploy-web.sh 后,再次刷新线上页面。
打开 Chrome (Chrome Web Browser, 谷歌浏览器) 开发者工具 -> Network,发现请求变了:
- Request URL (Uniform Resource Locator, 统一资源定位符):
http://47.108.xx.xx/auth/admin/captcha✅ - Status Code: 200 OK 🟢
完美!
- 浏览器不再请求 OSS (Object Storage Service, 对象存储服务) 域名,而是直接请求后端网关 IP (Internet Protocol, 互联网协议)。
- 路径里去掉了
/api,正好匹配网关的Path=/auth/**路由规则。 - 验证码图片顺利加载!
📊 流程与架构图解
1. 自动化部署流程 (Mermaid Flowchart)
2. 浏览器请求流转 (Mermaid Sequence Diagram)
3. 部署状态流转 (Mermaid State Diagram)
4. 前端网络模块类图 (Mermaid Class Diagram)
5. 部署实体关系图 (Mermaid ER Diagram)
🧠 知识点思维导图
-
Vue3 + OSS (Object Storage Service, 对象存储服务) 部署实战
- 核心痛点
- 本地开发正常 (
proxy生效) - 线上访问 404 (请求发往 OSS (Object Storage Service, 对象存储服务) 域名)
- 手动部署繁琐 (Build + Upload)
- 本地开发正常 (
- 根因分析
- Vite
server.proxy仅在 Dev (Development, 开发) 模式有效 - Axios
baseURL写死为/api - 浏览器将相对路径解析为当前 OSS (Object Storage Service, 对象存储服务) 域名
- Vite
- 解决方案
- DevOps (Development and Operations, 开发运维一体化) 脚本
- 工具:
ossutil(阿里云 CLI (Command Line Interface, 命令行界面)) - 动作: 动态生成
.env.production - 注入:
VITE_APP_BASE_API = 网关IP
- 工具:
- 代码改造
- 文件:
request.ts - 逻辑:
baseURL = import.meta.env... || '/api'
- 文件:
- DevOps (Development and Operations, 开发运维一体化) 脚本
- 关键收益
- 自动化: 一键部署 (30秒)
- 灵活性: IP (Internet Protocol, 互联网协议) 变动只需改脚本
- 高可用: 动静分离 (OSS (Object Storage Service, 对象存储服务) + ACK (Alibaba Cloud Container Service for Kubernetes, 阿里云容器服务 Kubernetes 版))
- 核心痛点
-
Vue3 + OSS (Object Storage Service, 对象存储服务) 部署实战
- 核心痛点
- 本地开发正常 (
proxy生效) - 线上访问 404 (请求发往 OSS (Object Storage Service, 对象存储服务) 域名)
- 手动部署繁琐 (Build + Upload)
- 本地开发正常 (
- 根因分析
- Vite
server.proxy仅在 Dev (Development, 开发) 模式有效 - Axios
baseURL写死为/api - 浏览器将相对路径解析为当前 OSS (Object Storage Service, 对象存储服务) 域名
- Vite
- 解决方案
- DevOps (Development and Operations, 开发运维一体化) 脚本
- 工具:
ossutil(阿里云 CLI (Command Line Interface, 命令行界面)) - 动作: 动态生成
.env.production - 注入:
VITE_APP_BASE_API = 网关IP
- 工具:
- 代码改造
- 文件:
request.ts - 逻辑:
baseURL = import.meta.env... || '/api'
- 文件:
- DevOps (Development and Operations, 开发运维一体化) 脚本
- 关键收益
- 自动化: 一键部署 (30秒)
- 灵活性: IP (Internet Protocol, 互联网协议) 变动只需改脚本
- 高可用: 动静分离 (OSS (Object Storage Service, 对象存储服务) + ACK (Alibaba Cloud Container Service for Kubernetes, 阿里云容器服务 Kubernetes 版))
- 核心痛点

155

被折叠的 条评论
为什么被折叠?



