13 KiB
AI 英语学习辅助平台 — 线上部署操作流程
项目概述
- 项目名称:AI 英语学习辅助平台
- 技术栈:Vue 3 + Vite + Vue Router(History 模式)
- 项目结构:纯前端静态文件(HTML / CSS / JS),可部署到任意静态托管服务
一、部署前准备
1.1 环境要求
| 工具 | 版本要求 | 用途 |
|---|---|---|
| Node.js | >= 18.x(推荐 20.x LTS) | 前端构建 |
| npm | >= 9.x | 包管理器 |
# 检查 Node.js 和 npm 版本
node -v
npm -v
1.2 安装依赖
# 安装前端依赖
cd AI_Demo
npm install
二、关键配置说明
2.1 API 配置(必须在部署前确认)
项目所有 API 密钥集中在 src/config/index.js,部署前请确认以下配置项均已填写正确:
| 配置项 | 说明 |
|---|---|
GRS_API_KEY |
GRS AI 接口密钥(作文批改) |
DOUBAO_KEY |
豆包 API 密钥 |
DOUBAO_APP_ID |
豆包语音 App ID |
DOUBAO_ACCESS_TOKEN |
豆包语音访问令牌 |
DOUBAO_RESOURCE_ID |
豆包 TTS 资源 ID |
DOUBAO_ASR_RESOURCE_ID |
豆包 ASR 资源 ID |
ARK_API_KEY |
火山引擎 Ark 大模型密钥(口语对话) |
ARK_MODEL |
Ark 模型名称(如 doubao-pro-4k) |
2.2 跨域响应头要求(重要)
项目使用了 @ffmpeg/ffmpeg(WebAssembly),需要服务器返回以下响应头:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
各部署平台的配置方式见下方对应章节。
2.3 API 代理配置(重要)
项目在开发环境通过 Vite 代理转发以下 API 请求,生产环境必须在服务器/网关层配置对应的反向代理:
| 前端请求路径前缀 | 代理目标 | 用途 | 备注 |
|---|---|---|---|
/tts-api |
https://openspeech.bytedance.com |
豆包 TTS 语音合成 | 需要反向代理 |
/ark-api |
https://ark.cn-beijing.volces.com |
火山引擎 Ark 大模型 | 需要反向代理 |
/dashscope-api |
https://dashscope.aliyuncs.com |
阿里云百炼 | 需要反向代理 |
/asr-ws |
wss://openspeech.bytedance.com |
豆包 ASR WebSocket | 需要反向代理+注入鉴权 Header |
ASR WebSocket 特殊说明:
/asr-ws代理需要在代理层注入以下鉴权 Header(浏览器原生 WebSocket 不支持自定义 Header):
X-Api-App-KeyX-Api-Access-KeyX-Api-Resource-IdX-Api-Connect-Id(每次连接随机 UUID)
三、构建生产包
3.1 前端构建
npm run build
构建完成后,产物位于 dist/ 目录,包含:
dist/
├── index.html
├── favicon.svg
└── assets/
├── *.js
└── *.css
可在本地预览构建结果:
npm run preview
四、部署方案
方案 A:Nginx 部署(推荐,自有服务器)
4.A.1 上传文件
将 dist/ 目录内容上传到服务器,例如 /var/www/ai-demo/:
scp -r dist/* user@your-server:/var/www/ai-demo/
4.A.2 Nginx 配置
创建或修改 Nginx 站点配置文件(如 /etc/nginx/sites-available/ai-demo.conf):
server {
listen 80;
server_name your-domain.com; # 替换为你的域名或 IP
root /var/www/ai-demo;
index index.html;
# 跨域响应头
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
# Vue Router History 模式:所有路由回退到 index.html
location / {
try_files $uri $uri/ /index.html;
}
# 代理:豆包 TTS
location /tts-api/ {
proxy_pass https://openspeech.bytedance.com/;
proxy_ssl_server_name on;
proxy_set_header Host openspeech.bytedance.com;
}
# 代理:火山引擎 Ark
location /ark-api/ {
proxy_pass https://ark.cn-beijing.volces.com/;
proxy_ssl_server_name on;
proxy_set_header Host ark.cn-beijing.volces.com;
}
# 代理:阿里云百炼
location /dashscope-api/ {
proxy_pass https://dashscope.aliyuncs.com/;
proxy_ssl_server_name on;
proxy_set_header Host dashscope.aliyuncs.com;
}
# 代理:豆包 ASR WebSocket(需注入鉴权 Header)
location /asr-ws/ {
proxy_pass https://openspeech.bytedance.com/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host openspeech.bytedance.com;
proxy_ssl_server_name on;
# 注入豆包 ASR 鉴权 Header(替换为实际值)
proxy_set_header X-Api-App-Key "YOUR_DOUBAO_APP_ID";
proxy_set_header X-Api-Access-Key "YOUR_DOUBAO_ACCESS_TOKEN";
proxy_set_header X-Api-Resource-Id "volc.bigasr.sauc.duration";
}
# 静态资源缓存
location /assets/ {
expires 1y;
add_header Cache-Control "public, immutable";
add_header Cross-Origin-Opener-Policy "same-origin" always;
add_header Cross-Origin-Embedder-Policy "require-corp" always;
}
}
#### 4.A.3 启用配置并重启 Nginx
```bash
# 启用站点(Ubuntu/Debian)
ln -s /etc/nginx/sites-available/ai-demo.conf /etc/nginx/sites-enabled/
# 检查配置语法
nginx -t
# 重载 Nginx
systemctl reload nginx
4.A.4 配置 HTTPS(推荐)
# 使用 Certbot 申请免费 SSL 证书
apt install certbot python3-certbot-nginx
certbot --nginx -d your-domain.com
方案 B:Node.js + Express 部署
适用于需要在 Node.js 环境中自定义响应头的场景。
创建前端静态服务器文件 frontend-server.js(项目根目录):
import express from 'express'
import { createProxyMiddleware } from 'http-proxy-middleware'
import { fileURLToPath } from 'url'
import path from 'path'
import crypto from 'crypto'
const __dirname = path.dirname(fileURLToPath(import.meta.url))
const app = express()
const PORT = process.env.PORT || 3000
// 第三方 API 代理
app.use('/tts-api', createProxyMiddleware({
target: 'https://openspeech.bytedance.com',
changeOrigin: true,
pathRewrite: { '^/tts-api': '' }
}))
app.use('/ark-api', createProxyMiddleware({
target: 'https://ark.cn-beijing.volces.com',
changeOrigin: true,
pathRewrite: { '^/ark-api': '' }
}))
app.use('/dashscope-api', createProxyMiddleware({
target: 'https://dashscope.aliyuncs.com',
changeOrigin: true,
pathRewrite: { '^/dashscope-api': '' }
}))
app.use('/asr-ws', createProxyMiddleware({
target: 'wss://openspeech.bytedance.com',
changeOrigin: true,
ws: true,
pathRewrite: { '^/asr-ws': '' },
on: {
proxyReqWs: (proxyReq) => {
proxyReq.setHeader('X-Api-App-Key', process.env.DOUBAO_APP_ID)
proxyReq.setHeader('X-Api-Access-Key', process.env.DOUBAO_ACCESS_TOKEN)
proxyReq.setHeader('X-Api-Resource-Id', 'volc.bigasr.sauc.duration')
proxyReq.setHeader('X-Api-Connect-Id', crypto.randomUUID())
}
}
}))
// 静态文件服务
app.use(express.static(path.join(__dirname, 'dist')))
// Vue Router History 模式回退
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})
app.listen(PORT, () => {
console.log(`Frontend server running at http://localhost:${PORT}`)
})
4.B.3 安装前端服务器依赖
# 在项目根目录安装
npm install express http-proxy-middleware
4.B.4 启动前端服务器
# 在项目根目录启动
DOUBAO_APP_ID=xxx DOUBAO_ACCESS_TOKEN=xxx pm2 start frontend-server.js --name ai-demo-frontend
# 查看两个服务的状态
pm2 status
# 设置开机自启
pm2 save
前端服务运行在 http://localhost:3000(提供静态文件和代理)
方案 C:EdgeOne Pages / Vercel / Netlify(纯静态托管)
注意:此类平台不支持服务端代理,
/tts-api、/ark-api、/dashscope-api、/asr-ws等接口将因跨域或缺少鉴权 Header 而失败。 建议仅用于演示。
部署步骤(以 Vercel 为例)
- 将项目推送到 GitHub
- 在 Vercel 控制台导入仓库
- 构建命令:
npm run build,输出目录:dist - 创建
vercel.json配置 History 模式路由回退和响应头:
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }],
"headers": [
{
"source": "/(.*)",
"headers": [
{ "key": "Cross-Origin-Opener-Policy", "value": "same-origin" },
{ "key": "Cross-Origin-Embedder-Policy", "value": "require-corp" }
]
}
]
}
五、部署后验证清单
5.1 部署验证
| 验证项 | 检查方法 |
|---|---|
| 页面正常加载 | 访问首页,确认功能卡片显示正常 |
| 路由刷新不 404 | 直接访问 /pronunciation、/speaking 等子路由 |
| COOP/COEP 响应头 | 浏览器 DevTools → Network → 查看 index.html 响应头 |
| TTS 语音合成 | 进入发音练习页,测试语音播放 |
| ASR 语音识别 | 进入口语对话页,测试麦克风录音识别 |
| 作文批改 | 进入作文批改页,提交一段英文作文 |
| 试题分析 | 进入试题分析页,上传图片或输入题目 |
| 单词拼写练习 | 进入单词拼写页,测试拼写检测功能 |
六、常见问题排查
Q1:页面报错 SharedArrayBuffer is not defined
原因:服务器未返回 Cross-Origin-Opener-Policy: same-origin 和 Cross-Origin-Embedder-Policy: require-corp 响应头。
解决:参考第二节 2.2,在 Nginx 或 Node.js 服务器中添加对应响应头。
Q2:刷新页面出现 404
原因:Vue Router 使用 History 模式,服务器未配置路由回退。
解决:Nginx 添加 try_files $uri $uri/ /index.html;,Node.js 添加通配路由返回 index.html。
Q3:API 请求跨域报错(CORS)
原因:生产环境未配置反向代理,浏览器直接请求第三方 API 被跨域拦截。 解决:参考第二节 2.3,在 Nginx 或 Node.js 中配置对应代理规则。
Q4:ASR 语音识别 WebSocket 连接失败
原因:代理未注入豆包 ASR 鉴权 Header,或 WebSocket 升级配置缺失。
解决:确认 Nginx 配置中包含 proxy_set_header Upgrade $http_upgrade; 及三个 X-Api-* Header。
Q5:构建时内存不足
原因:项目依赖较多,构建产物较大。 解决:
# 增大 Node.js 内存限制
NODE_OPTIONS=--max-old-space-size=4096 npm run build
七、页面路由清单
| 路由路径 | 页面名称 | 功能说明 |
|---|---|---|
/ |
首页 | 功能导航卡片 |
/pronunciation |
发音练习 | TTS 语音合成,音标学习 |
/speaking |
口语对话 | ASR 语音识别,AI 对话 |
/essay-correction |
作文批改 | 图片/文本作文批改 |
/exam-analysis |
试题分析 | 图片题目分析解答 |
/spell-practice |
单词拼写 | 单词拼写练习检测 |
/problem-solving |
解题指导 | AI 解题步骤指导 |
/question-generator |
题目生成 | 自动生成练习题 |
/question-variant |
题目变体 | 生成相似题目变体 |
/audio-to-text |
语音转文字 | 音频转文本功能 |
八、依赖版本参考
前端依赖(package.json)
| 依赖包 | 版本 |
|---|---|
| vue | ^3.5.30 |
| vue-router | ^5.0.3 |
| vite | ^8.0.0 |
| @ffmpeg/ffmpeg | ^0.12.15 |
| @ffmpeg/util | ^0.12.2 |
| axios | ^1.13.6 |
| marked | ^17.0.5 |
| pako | ^2.1.0 |
九、目录结构参考
AI_Demo/
├── dist/ # 前端构建产物(部署此目录)
├── src/ # 前端源码
│ ├── config/index.js # API 密钥配置(部署前确认)
│ ├── router/index.js # 路由定义
│ ├── views/ # 页面组件
│ │ ├── HomePage.vue # 首页
│ │ ├── Pronunciation.vue # 发音练习
│ │ ├── Speaking.vue # 口语对话
│ │ ├── EssayCorrection.vue # 作文批改
│ │ ├── ExamAnalysis.vue # 试题分析
│ │ ├── SpellPractice.vue # 单词拼写
│ │ ├── ProblemSolving.vue # 解题指导
│ │ ├── QuestionGenerator.vue # 题目生成
│ │ ├── QuestionVariant.vue # 题目变体
│ │ └── AudioToText.vue # 语音转文字
│ ├── components/ # 公共组件
│ ├── assets/ # 静态资源
│ └── MainLayout.vue # 布局组件
├── vite.config.js # 开发代理配置(生产环境需在服务器复现)
├── package.json # 前端依赖配置
└── DEPLOY.md # 本文档
十、Docker 部署(可选)
10.1 构建镜像
FROM node:20-alpine
WORKDIR /app
# 复制依赖文件
COPY package*.json ./
RUN npm ci --only=production
# 复制源码
COPY . ./
# 构建
RUN npm run build
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
十一、安全建议
- HTTPS 强制:生产环境务必启用 HTTPS
- API 密钥保护:不要将 API 密钥提交到代码仓库
- 输入验证:对用户输入进行验证和过滤
- 日志审计:记录关键操作和错误信息
十二、更新与维护
更新前端
git pull
npm install
npm run build
# 重新部署 dist/ 目录
文档版本:v2.1
更新日期:2025-04-16
更新内容:移除视频讲解功能及相关后端服务