问题描述
vue3编译打包,发布到fastapi静态目录下,刷新不能正常显示
分析
Vue3 路由默认是 history 模式,刷新页面时浏览器会把前端路由路径当成后端接口请求,FastAPI 找不到对应接口就返回 Not Found。
解决方案1:改用 hash 路由
优点:最简单,只改前端,不用改后端
缺点:地址栏会带 #
步骤1
修改 src/router/index.js
import { createRouter, createWebHashHistory } from 'vue-router' // 改用 createWebHashHistory
const router = createRouter({
history: createWebHashHistory(import.meta.env.BASE_URL),
routes: [...]
})
export default router
步骤2
在项目 根目录 或 src 目录下,找到或新建一个名为 vite-env.d.ts(或者 env.d.ts、global.d.ts)的声明文件,在里面加上这一行代码即可:
/// <reference types="vite/client" />
步骤3
重新打包放入 FastAPI static 目录,刷新正常。
解决方案2:保留 history 路由
优点:地址栏不改版
缺点:复杂,后端配置兜底,可能会失效
1. FastAPI 配置静态文件 + 路由兜底
假设前端打包文件放在项目 static 文件夹,完整代码:
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import os
app = FastAPI()
# 挂载静态目录
app.mount("/", StaticFiles(directory="static", html=True), name="static")
# 兜底路由:所有未匹配的请求都返回 index.html
@app.get("/{full_path:path}")
async def catch_all(full_path: str):
index_path = os.path.join("static", "index.html")
return FileResponse(index_path)
2. 关键说明
StaticFiles(directory="static", html=True):正常访问静态资源、首页/{full_path:path}全匹配路由:所有前端路由刷新、深层路径都会返回index.html,由 Vue 接管路由
目录结构参考
你的FastAPI项目/
├── main.py
└── static/ # Vue打包后的dist里所有文件丢这里
├── index.html
├── assets/
└── ...
额外排查点
- 确认
static目录名、路径和代码里一致 - 打包时 Vue 的
vite.config.js不要配置错误base:export default defineConfig({ base: "/", // 根路径,不要写 /xxx/ }) - 重启 FastAPI 服务生效