FastAPI如何解决跨越问题

一、什么是跨域问题

跨域资源共享(CORS)是浏览器的一种安全机制。当一个在浏览器中运行的前端应用,其 JavaScript 代码尝试与不同源的后端通信时,就会产生跨域请求。

什么是"源"?

源由三部分组成:

  • 协议(http / https)

  • 域名 (myapp.com / localhost)

  • 端口(80 / 443 / 8080)

只要协议、域名、端口中任意一个不同,就属于不同源。例如,即使都在 localhost 上,http://localhost:5173 和 http://localhost:8000 也是不同的源。

前端 后端 是否跨域
http://localhost:5173 http://localhost:8000 ✅ 跨域
http://example.com http://api.example.com ✅ 跨域
http://example.com http://example.com ❌ 不跨域

二、跨域问题长什么样?

假设前端 Vue 应用运行在 http://localhost:5173,后端 FastAPI 运行在 http://127.0.0.1:8000。当前端向后端发起请求时,浏览器会拦截并报错:

复制代码
Access to XMLHttpRequest at 'http://127.0.0.1:8000/api/news' 
from origin 'http://localhost:5173' 
has been blocked by CORS policy: 
No 'Access-Control-Allow-Origin' header is present on the requested resource.

这是浏览器同源策略在起作用------它默认阻止不同源之间的资源访问。如果没有正确配置 CORS,前端应用将无法调用后端 API。

三、FastAPI 如何解决跨域问题

FastAPI 内置了 CORSMiddleware 中间件,只需几步配置即可解决跨域问题。

第一步:导入 CORSMiddleware

复制代码
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

第二步:配置允许的源

复制代码
app = FastAPI()

# 配置允许跨域访问的源列表
origins = [
    "http://localhost",
    "http://localhost:5173",    # Vue 开发服务器默认端口
    "http://localhost:8080",
    "https://your-production-domain.com",
]

第三步:添加 CORS 中间件

复制代码
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,          # 允许的源
    allow_credentials=True,         # 允许携带 Cookie
    allow_methods=["*"],            # 允许所有 HTTP 方法
    allow_headers=["*"],            # 允许所有请求头
)

完成以上配置后,前端即可正常调用后端接口。

四、CORSMiddleware 核心参数详解

参数 说明 示例
allow_origins 允许跨域请求的源列表 ["http://localhost:5173"] 或 ["*"]
allow_origin_regex 使用正则表达式匹配允许的源 "https://.*\.example\.com"
allow_methods 允许的 HTTP 方法 ["GET", "POST", "PUT", "DELETE"] 或 ["*"]
allow_headers 允许的请求头 ["Content-Type", "Authorization"] 或 ["*"]
allow_credentials 是否允许跨域请求携带凭证(Cookie、Authorization 头等) True 或 False
expose_headers 允许浏览器访问的响应头 ["X-Custom-Header"]
max_age 浏览器缓存预检请求结果的时间(秒) 3600

注意 :CORSMiddleware 的默认参数非常保守,必须显式配置才能允许跨域请求。

五、allow_origins=["*"] 的坑

允许所有源看似最简单,但有重要限制:

复制代码
五、allow_origins=["*"] 的坑
允许所有源看似最简单,但有重要限制:

原因 :当 allow_credentials=True 时,allow_origins 不能是 ["*"],必须指定具体的源(冲突是有条件的 ------只有当请求实际携带凭证时,浏览器才会拒绝。)

复制代码
# ✅ 正确做法:明确列出允许的源
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173", "https://example.com"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

六、开发环境 vs 生产环境配置

开发环境(宽松配置)

复制代码
app.add_middleware(
    CORSMiddleware,
    allow_origins=["http://localhost:5173", "http://localhost:3000", "http://127.0.0.1:5173"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

生产环境(严格配置)

生产环境应只允许可信的源:

复制代码
app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "https://example.com",
        "https://www.example.com",
    ],
    allow_credentials=True,
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Content-Type", "Authorization"],
    max_age=3600,  # 缓存预检请求 1 小时
)

最佳实践:将允许的源放在环境变量中,避免硬编码:

复制代码
import os

ALLOWED_ORIGINS = os.getenv("ALLOWED_ORIGINS", "").split(",")

app.add_middleware(
    CORSMiddleware,
    allow_origins=ALLOWED_ORIGINS,
    # ...
)

七、完整代码示例

复制代码
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

# 配置 CORS
origins = [
    "http://localhost:5173",    # Vue 开发环境
    "http://localhost:3000",    # React 开发环境
    "https://your-domain.com",  # 生产环境
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
async def root():
    return {"message": "Hello World"}

八、总结

步骤 操作
1 from fastapi.middleware.cors import CORSMiddleware
2 定义 origins 列表,包含允许的前端源
3 调用 app.add_middleware(CORSMiddleware, ...) 配置参数
4 特别注意:allow_credentials=True 时不能用 allow_origins=["*"]
5 生产环境只允许可信源,使用环境变量管理

配置完 CORS 中间件后,浏览器会收到后端返回的 Access-Control-Allow-Origin 响应头,从而允许跨域请求正常进行。

相关推荐
LK_073 天前
【FastAPI】基础篇 01|开始之前:API、HTTP 与 FastAPI 到底是什么
网络协议·http·fastapi
一枕槐安4878 天前
Qwen 通义千问本地部署与推理服务封装
fastapi·qwen·vllm·流式推理·openai兼容api·awq量化
在努力的前端小白8 天前
基于FastAPI+LangChain+LangGraph+Agent+多模态的AI Agent 有渔渔具网站
人工智能·langchain·vue·fastapi
sun_weitao8 天前
用 FastAPI + MQTT 做一个 ESP32最小化跑通示例
中间件·vue·fastapi
峯5809 天前
一文学习FastAPI
学习·fastapi
TheBestRucy11 天前
从零构建企业级“中文法律智能问答系统”:FastAPI+Milvus+混合检索+真流式RAG实战
fastapi·milvus
卡提西亚11 天前
FastAPI基础入门
python·fastapi
Paper-Tiger12 天前
手搓 FastAPI + Redis + 流式 RAG 实录
fastapi
像风一样自由202012 天前
2.如何用FastAPI把一个Python算法封装成HTTP服务
python·算法·fastapi
狗凯之家源码网12 天前
iOS C2 V2 与 Python FastAPI 全链路远控系统深度评测
python·ios·fastapi