FastAPI如何解决跨越问题

一、什么是跨域问题

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

什么是"源"?

源由三部分组成:

  • 协议(http / https)

  • 域名myapp.com / localhost)

  • 端口(80 / 443 / 8080)

只要协议、域名、端口中任意一个不同,就属于不同源。例如,即使都在 localhost 上,http://localhost:5173http://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 头等) TrueFalse
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 响应头,从而允许跨域请求正常进行。

相关推荐
the局外人2 小时前
学习 FastAPI 的 Day 3:企业级目录与数据库迁移
后端·python·fastapi
梦因you而美20 小时前
LangChain-ReAct-Agent 智能客服系统 · 项目技术文档
langchain·agent·fastapi·扫地机器人·langgraph·rag 检索增强·react 智能客服
jsjzsl21 天前
独立自由度框架下位置自由度的本体论特征、物理现象与新技术路径
python·flask·fastapi
嘻哈baby1 天前
FastAPI + SQLite 从 0 写一个真正能用的待办 API
数据库·sqlite·fastapi
陈驰_05041 天前
需求列表接口 422 Unprocessable Entity 排查与修复全记录
状态模式·fastapi·vue 3
Json____1 天前
基于 FastAPI + Vue3 的在线拍卖系统技术解析
spring boot·后端·fastapi·wwwoop.com
创新技术阁1 天前
FastapiAdmin 实战:二次开发前的准备(环境配置与项目启动)
前端·后端·fastapi
神秘的猪头2 天前
新版 LangChain Agent 核心架构:State、Context、ToolRuntime 与 Middleware
langchain·llm·fastapi
神秘的猪头2 天前
新版 LangChain Agent 入门:从 `bind_tools + while` 到 `create_agent`
langchain·fastapi
神秘的猪头2 天前
把新版 LangChain Agent 做成真正应用:Memory、Streaming、SSE 与 Structured Output
langchain·fastapi