第一步:发现错误(What Broke?)
报错信息原文:

错误原因:
CORS 跨域错误:缺少 / 无效 Access-Control-Allow-Origin 响应头
你遇到的是前端跨域请求被浏览器拦截的标准问题,核心原因:后端没有返回合法的 Access-Control-Allow-Origin 响应头,浏览器安全策略直接阻止了请求。
第二步:解决错误
我们首先查看前端 api.js 和 vite.config.js 文件。
这两个文件是 Vue3 + Vite 项目中的核心配置文件,分别负责项目构建环境配置和前端 API 接口统一管理。以下是详细的功能拆解:
1. vite.config.js ------ 项目构建与开发服务配置
这是 Vite 构建工具的核心配置文件,用于定义项目的构建规则、插件挂载和开发服务器参数。
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// 导出 Vite 配置
export default defineConfig({
// 注册 Vue 官方插件,用于支持 Vue3 单文件组件(.vue)的编译解析
plugins: [vue()],
})
核心功能
- 插件管理 :通过
plugins数组挂载 Vite 官方 / 第三方插件(这里是@vitejs/plugin-vue,支持 Vue3 语法编译)。 - 基础构建配置:可扩展配置端口号、跨域代理、环境变量、打包输出路径、依赖预构建等(当前为初始默认配置)。
- 环境适配:区分开发环境 / 生产环境的构建逻辑,是 Vite 项目的 "配置中枢"。
2. api.js ------ 前端 API 统一配置管理
这是前端项目的接口配置中心,用于统一管理后端接口地址、第三方 API 密钥、请求基础路径等公共参数,避免代码中硬编码 URL / 密钥。
核心代码解析
js
// 后端API基础URL配置(本地后端服务地址)
export const apiConfig = {
baseURL: 'http://127.0.0.1:8009',
}
// 第三方AI接口配置(阿里通义千问)
export const aiChatConfig = {
apiEndpoint: 'https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions',
apiKey: 'sk-9c4d89982a6a4bd3b7494d94751fe81c',
model: 'qwen3-max-preview'
}
核心功能
- 后端接口统一管理 :将后端服务的基础地址抽离为
baseURL,后续接口请求只需基于该地址拼接路径,方便后端地址更换时只改一处。 - 第三方 API 配置 :集中存储阿里通义千问 AI 对话接口的端点、API 密钥(
apiKey)、调用模型(model),避免在业务代码中直接暴露敏感信息。 - 配置解耦:将所有接口相关的公共参数集中管理,降低代码维护成本,方便不同环境(开发 / 测试 / 生产)切换时快速调整配置。
关联说明
vite.config.js 可通过配置 server.proxy 实现前端跨域代理,间接解决跨域问题(比如将 /api 请求转发到 http://127.0.0.1:8009);而 api.js 中的 baseURL 则是接口请求的基础地址,两者配合可实现前端接口请求的规范化和跨域处理。
1. api.js 修改前后对比
修改前
js
export const apiConfig = {
baseURL: 'http://127.0.0.1:8009', // 直接写后端完整地址
}
export const aiChatConfig = {
apiEndpoint: 'https://dashscope.aliyuncs.com/...',
apiKey: 'sk-xxxx',
model: 'qwen3-max-preview'
}
修改后
js
export const apiConfig = {
baseURL: '/api', // 改成相对路径 /api
};
export const aiChatConfig = {
baseURL: '/api', // 也改成相对路径 /api
};
🎯 为什么这么改?
- 解决跨域(CORS)的核心前提 :浏览器的同源策略会拦截「前端域名(
localhost:5173)」和「后端域名(127.0.0.1:8009)」端口不同的请求。把baseURL改成相对路径/api,是为了让前端请求走 Vite 代理,而不是直接请求后端地址,从根源上绕开浏览器的跨域拦截。 - 统一请求入口 :所有以
/api开头的请求,都会被 Vite 自动转发到后端,前端代码里不用再写死 IP 和端口,后续部署到服务器时,只需要改vite.config.js的target,前端代码完全不用动,更易维护。 - 修复了「找不到导出」的报错 :你之前的
aiChatConfig是阿里云通义千问的配置,项目里的AIChat.vue等文件在导入时,会因为你修改了配置结构导致找不到导出。把aiChatConfig也改成baseURL: '/api',是为了让 AI 聊天接口也走代理,同时保证导出结构和项目导入代码完全匹配,彻底解决No matching export报错。
2. vite.config.js 修改前后对比
修改前
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
})
修改后
js
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
// 新增:跨域代理
server: {
proxy: {
'/api': {
target: 'http://127.0.0.1:9000', // 后端地址
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, '')
}
}
},
// 新增:忽略 fsevents 错误
optimizeDeps: {
exclude: ['fsevents']
}
})
为什么这么改?
① 新增 server.proxy 代理配置
核心作用 :实现「前端请求 /api/xxx → Vite 转发到 http://127.0.0.1:9000/xxx」
关键参数解释:
target:后端服务的真实地址(注意你这里改成了9000端口,要和后端实际启动的端口一致!)changeOrigin: true:修改请求头的 Origin,让后端认为请求来自同源,避免跨域校验rewrite:把请求路径里的/api去掉,比如/api/news会被转发为/news,和后端接口路径匹配
② 新增 optimizeDeps.exclude: ['fsevents']
核心作用 :解决 Windows 系统下的 fsevents.node 报错
原理 :fsevents 是 Mac 系统专用的文件监听库,Windows 系统不支持,Vite 会尝试加载它导致报错。
加这一行后,Vite 会直接忽略这个依赖,不再尝试加载,彻底消除这个无关报错。
必须在 FastAPI 中添加 CORS 中间件!
main.py 代码(必须修改)
python
# main.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
app = FastAPI()
# 添加 CORS 中间件(关键!)
app.add_middleware(
CORSMiddleware,
# 前端运行地址(Vite 默认 5173)我的电脑默认
allow_origins=["*"],#开发写型号没问题,部署时需要修改
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# 示例接口
@app.get("/")
async def root():
return {"message": "Hello World"}
重点解释:
| 配置项 | 说明 |
|---|---|
allow_origins=["http://localhost:5173"] |
前端地址,必须精确匹配 ,不能用 *(安全风险) |
allow_credentials=True |
支持 token、cookie |
allow_methods=["*"] |
所有 HTTP 方法(GET/POST) |
allow_headers=["*"] |
所有请求头 |
第六步:重启服务
bash
uvicorn main:app --reload --port 9000
重启后,FastAPI 会加载 CORS 中间件
第七步:重启前端
bash
npm run dev
打开浏览器:
http://localhost:5173
第八步:验证结果(Confirm Fix)
打开浏览器开发者工具 → Network
| 项目 | 是否正常 |
|---|---|
| 请求路径 | http://localhost:5173/api/news |
| 实际地址 | http://127.0.0.1:9000/api/news(代理) |
| 状态码 | 200 OK |
| Headers | ✅ 包含 Access-Control-Allow-Origin: http://localhost:5173 |
| Response | ✅ JSON 数据正常显示 |
最后总结:错误解决全链路
| 步骤 | 内容 | 实际意义 |
|---|---|---|
| 1. 发现错误 | Access-Control-Allow-Origin: missing |
现象:数据被屏蔽 |
| 2. 分析错误 | 代理没问题,curl 能通 → 问题在头 | 锁定为后端缺失 CORS |
| 3. 排查错误 | 用 curl 测试 → 无 CORS 头 |
确认后端未返回头 |
| 4. 定位根因 | FastAPI 默认不提供 CORS 头 | 你漏了 CORSMiddleware |
| 5. 解决错误 | 在 main.py 添加 CORS 中间件 |
✅ 修复成功 |
| 6. 验证结果 | 数据正常加载,CORS 头存在 | ✅ 问题彻底解决 |