FastAPI 跨域问题解决方案

在 FastAPI 中解决跨域问题(CORS)主要有以下几种方法:

1. 使用 CORSMiddleware(推荐)

这是最常用的方法,FastAPI 提供了内置的中间件来处理 CORS:

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

app = FastAPI()

# 设置允许的源列表
origins = [
    "http://localhost",
    "http://localhost:8080",
    "http://localhost:3000",
    "https://your-frontend-domain.com",
]

# 添加 CORS 中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,  # 允许的源列表
    allow_credentials=True,  # 允许携带 cookie
    allow_methods=["*"],  # 允许所有方法
    allow_headers=["*"],  # 允许所有头
)

2. 允许所有源(开发环境使用)

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],  # 允许所有源
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

⚠️ 注意:生产环境中不建议使用 allow_origins=["*"],这会有安全风险。

3. 更精细的控制

app.add_middleware(
    CORSMiddleware,
    allow_origins=["https://example.com"],  # 只允许特定域名
    allow_methods=["GET", "POST"],  # 只允许特定方法
    allow_headers=["X-Custom-Header"],  # 只允许特定头
    max_age=600,  # 预检请求缓存时间(秒)
)

4. 手动设置响应头(不推荐)

如果不想使用中间件,也可以手动设置响应头:

from fastapi import FastAPI, Response

app = FastAPI()

@app.get("/")
async def main(response: Response):
    response.headers["Access-Control-Allow-Origin"] = "*"
    response.headers["Access-Control-Allow-Methods"] = "GET, POST"
    response.headers["Access-Control-Allow-Headers"] = "Content-Type"
    return {"message": "Hello World"}

常见问题

​​预检请求(OPTIONS)处理​​:CORSMiddleware 会自动处理 OPTIONS 请求,无需手动处理。

​​带凭证的请求​​:如果需要发送 cookies 或认证头,需要设置 allow_credentials=True,并且 allow_origins不能为 ["*"]。

​​Vue/React 开发环境​​:确保前端开发服务器的地址在 allow_origins列表中。

选择哪种方法取决于你的具体需求和安全考虑。对于大多数应用,第一种方法是最佳选择。