在现代 Web 开发中,前后端分离已经是标准范式。后端使用 FastAPI 提供 RESTful 接口,前端使用 Vue.js 构建动态交互界面。然而,当前端(例如运行在 localhost:5173)尝试访问后端(localhost:8000)时,浏览器的同源策略(SOP)会无情地抛出 CORS(跨域资源共享)错误。

本文将演示如何在 FastAPI 中优雅地配置 CORS,并使用 Vue 3 (Composition API) 顺畅地获取数据。

FastAPI 端的 CORS 配置

FastAPI 内置了强大的中间件机制,处理跨域问题只需要引入 CORSMiddleware

main.py

from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel

app = FastAPI()

# 配置允许跨域的源列表
origins = [
    "http://localhost:5173",  # Vue 3 Vite 默认开发端口
    "http://127.0.0.1:5173",
    # "https://your-production-domain.com", # 生产环境域名
]

# 添加 CORS 中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,       # 允许的源
    allow_credentials=True,      # 允许携带 Cookie 等凭证
    allow_methods=["*"],         # 允许的 HTTP 方法 (GET, POST, PUT, DELETE 等)
    allow_headers=["*"],         # 允许的请求头
)

# 模拟的数据库数据
class User(BaseModel):
    id: int
    username: str
    role: str

@app.get("/api/users", response_model=list[User])
async def get_users():
    return [
        {"id": 1, "username": "admin_alice", "role": "admin"},
        {"id": 2, "username": "dev_bob", "role": "developer"}
    ]

通过以上配置,FastAPI 会在 HTTP 响应头中自动注入 Access-Control-Allow-Origin 等字段,告诉浏览器:“这个前端域名是自己人,放行请求。”

Vue.js 端的数据请求

在 Vue 3 项目中,我们通常使用 fetchaxios 来发起请求。这里展示一个基于原生 fetch 和 Composition API 的组件。

UserList.vue

<template>
  <div class="user-container">
    <h2>系统用户列表</h2>
    <ul v-if="users.length > 0">
      <li v-for="user in users" :key="user.id">
        <span class="username">{{ user.username }}</span> 
        <span class="role">({{ user.role }})</span>
      </li>
    </ul>
    <p v-else-if="loading">加载中...</p>
    <p v-else class="error">{{ errorMsg }}</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'

const users = ref([])
const loading = ref(true)
const errorMsg = ref('')

const fetchUsers = async () => {
  try {
    // 请求 FastAPI 后端接口
    const response = await fetch('http://127.0.0.1:8000/api/users')
    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }
    const data = await response.json()
    users.value = data
  } catch (error) {
    console.error("获取数据失败:", error)
    errorMsg.value = "无法连接到服务器,请检查后端是否运行。"
  } finally {
    loading.value = false
  }
}

// 组件挂载时触发数据获取
onMounted(() => {
  fetchUsers()
})
</script>

<style scoped>
/* 简单的样式 */
.user-container { padding: 20px; }
.username { font-weight: bold; }
.role { color: #666; margin-left: 8px; }
.error { color: red; }
</style>

总结

通过 FastAPI 的 CORSMiddleware,我们可以极其细粒度地控制跨域权限,既保证了开发时的便利性,也为生产环境的安全留足了配置空间。结合 Vue 3 响应式系统,前后端的数据流转变得清晰且高效。