3.全局中间件_洋葱模型执行机制_跨域CORS配置

一、 中间件的核心定义与洋葱模型

1. 什么是中间件?

中间件(Middleware)是一个在每次 HTTP 请求进入 FastAPI 应用时都会被自动执行的全局拦截函数

它在请求到达具体路由函数之前 运行一次(前置拦截),并在路由函数执行完毕、响应返回给客户端之前再运行一次(后置处理)。

2. 洋葱模型(Onion Architecture)执行流

如果有多个中间件(如中间件 A 和中间件 B),执行顺序严格遵循"洋葱模型":

text 复制代码
客户端请求 ➡️ [中间件 A 前置] ➡️ [中间件 B 前置] ➡️ 【路由处理函数】 ➡️ [中间件 B 后置] ➡️ [中间件 A 后置] ➡️ 客户端响应
  • 请求阶段(由外向内):中间件 A 选执行,随后传递给中间件 B,最后到达路由函数。
  • 响应阶段(由内向外):路由函数返回后,中间件 B 的后置代码先执行,最后由中间件 A 后置代码打包返回给客户端。

二、 中间件的五大典型应用场景

场景分类 核心功能 典型案例
1. 性能监控 统计每个 API 接口的执行耗时 在 Response Header 中注入 X-Process-Time
2. 日志记录 全局打印/记录请求路径、IP 及响应状态码 记录所有 API 访问日志
3. 跨域处理 (CORS) 允许前端不同域名/端口跨域访问 使用 FastAPI 内置的 CORSMiddleware
4. 身份认证与拦截 拦截非法请求/校验 Token 校验 Headers 中的 Authorization 凭证
5. 响应头/安全篡改 统一为所有响应添加安全防防御 Header 注入 X-Frame-Options 或防盗链 Header

三、 FastAPI 中间件代码实现语法

python 复制代码
import time
from fastapi import FastAPI, Request

app = FastAPI()

# 使用 @app.middleware("http") 装饰器声明 HTTP 中间件
@app.middleware("http")
async def add_process_time_header(request: Request, call_next):
    # --------------------------------------------------
    # 1. 前置拦截处理(请求到达路由函数之前)
    # --------------------------------------------------
    start_time = time.time()
    
    # --------------------------------------------------
    # 2. 传递请求给后续的中间件或路由处理函数
    # --------------------------------------------------
    response = await call_next(request)
    
    # --------------------------------------------------
    # 3. 后置拦截处理(路由函数执行完毕,准备返回客户端之前)
    # --------------------------------------------------
    process_time = time.time() - start_time
    # 统一在响应头中添加接口耗时 (单位:秒)
    response.headers["X-Process-Time"] = str(process_time)
    
    return response

关键参数解密

  • request: Request:包含客户端请求的所有信息(Header、IP、Path、Method 等)。
  • call_next:一个异步回调函数。调用 await call_next(request) 意为"将请求交由下一个中间件或对应的视图函数去处理,并获取其返回的 response"。
  • response:视图函数计算完毕后返回的 HTTP 响应对象。在 return response 之前可以对其 Header、Cookie 进行修改。

四、 内置官方中间件:CORS 跨域资源共享配置

1. 什么是跨域报错 (CORS Error)?

这是所有前后端分离项目都会遇到的第一个"死穴"。 出于安全考虑,浏览器天生带有**"同源策略"**机制。比如你的前端(Vue/React)跑在 http://localhost:8080,而去请求跑在 http://localhost:8000 的 FastAPI 后端接口时。因为它们的端口不一样(不同源),浏览器就会认为有安全风险,直接把请求拦截死,并在控制台报出一片红色的 CORS Error 报错。

2. 标准跨域放行配置

要解决这个问题,不用自己手写逻辑,FastAPI 官方已经内置了强大的 CORSMiddleware,只需要把它挂载到中间件洋葱模型的外层即可:

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

app = FastAPI()

# 1. 设置允许访问的白名单源(前端的地址)
origins = [
    "http://localhost:8080",
    "http://localhost:3000",
    "https://my-frontend-website.com"
]

# 2. 将 CORS 中间件加入洋葱模型
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,     # 允许哪些前端地址跨域访问(如果写 ["*"] 则允许所有,但极不安全)
    allow_credentials=True,    # 是否允许前端携带 Cookie 等凭据
    allow_methods=["*"],       # 允许跨域请求的方法(GET, POST, PUT, DELETE等,"*"表示全放行)
    allow_headers=["*"],       # 允许跨域携带的请求头
)

【重点避坑】 :线上环境绝对禁止allow_origins 写成 ["*"] 且同时开启 allow_credentials=True,这不仅非常危险,而且很多浏览器会强制拒绝这种配置。务必老老实实配置具体的白名单域名!


五、 全局大串联 (终极总结)

1. 全链路协同思维链条

[收到请求] ➡️ [执行 CORS 等前置中间件拦截] ➡️ [抵达具体路由逻辑] ➡️ [执行中间件后置耗时统计] ➡️ [打上自定义 Header] ➡️ [响应出包给前端]

2. 【终极一句话速记】

"中间件像洋葱圈,一进一出跑两圈;跨域拦在最外层,配好白名单保平安。"

相关推荐
IT_陈寒1 小时前
Java空指针这次真把我坑惨了
前端·人工智能·后端
moMo2 小时前
LangChain 到 LangGraph: RAG 知识库改造
后端
用户574385305112 小时前
元数据驱动的通用 CRUD 后端框架 (3- createBusiness 工厂:三层装配 + 一行出 REST)
后端
高级程序源2 小时前
django大学生创新创业项目管理系统94923-计算机课程设计、毕业设计
javascript·vue.js·spring boot·后端·python·django·课程设计
Sam_Deep_Thinking3 小时前
new Thread()之后发生了什么?
java·后端·面试·程序员
步行cgn3 小时前
Spring util 命名空间详解
java·后端·spring
打工仔折腾 AI4 小时前
普通摄像头接入AI识别:绿联NAS部署Frigate监控实战
人工智能·后端·python·性能优化·ai agent 实战
万物智能6 小时前
SARADC模数转换—【万物智能之开源鸿蒙OpenHarmony系统实战开发系列教程】
前端·后端
花间相见6 小时前
【后端开发|网络编程】—— 五种实时通信方案全解析:短轮询、长轮询、SSE、MQTT、WebSocket
后端·网络协议