Starlette 中间件深度解析:从基础到高级应用

Starlette 中间件深度解析:从基础到高级应用

starlette The little ASGI framework that shines. 🌟 starlette 项目地址: https://gitcode.com/gh_mirrors/st/starlette

什么是 Starlette 中间件?

Starlette 中间件是一种强大的机制,允许开发者在请求处理流程的不同阶段插入自定义逻辑。这些中间件遵循 ASGI 规范,不仅适用于 Starlette 应用,也能与任何兼容 ASGI 的框架协同工作。

中间件的基本使用

在 Starlette 中,中间件通过 middleware 参数配置,确保它们被异常处理器正确包裹:

from starlette.applications import Starlette
from starlette.middleware import Middleware
from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware
from starlette.middleware.trustedhost import TrustedHostMiddleware

routes = [...]

middleware = [
    Middleware(
        TrustedHostMiddleware,
        allowed_hosts=['example.com', '*.example.com'],
    ),
    Middleware(HTTPSRedirectMiddleware)
]

app = Starlette(routes=routes, middleware=middleware)

默认中间件

每个 Starlette 应用默认包含两个中间件:

  1. ServerErrorMiddleware:最外层中间件,处理 500 错误和调试模式下的异常追踪
  2. ExceptionMiddleware:为特定异常类型关联处理函数

中间件执行顺序

中间件按照从上到下的顺序执行,执行流程如下:

ServerErrorMiddleware
    ↓
TrustedHostMiddleware
    ↓
HTTPSRedirectMiddleware
    ↓
ExceptionMiddleware
    ↓
路由系统
    ↓
端点处理

常用中间件详解

1. CORSMiddleware(跨域资源共享)

用于处理浏览器的跨域请求,通过添加适当的 CORS 头部实现。

from starlette.middleware.cors import CORSMiddleware

middleware = [
    Middleware(
        CORSMiddleware,
        allow_origins=['https://example.com'],
        allow_methods=['GET', 'POST'],
        allow_headers=['X-Custom-Header']
    )
]
重要参数:
  • allow_origins:允许的源列表
  • allow_methods:允许的 HTTP 方法
  • allow_headers:允许的请求头
  • max_age:CORS 响应缓存时间
全局 CORS 处理建议

为确保所有响应(包括错误响应)都包含 CORS 头部,建议将整个应用包装在 CORSMiddleware 中:

app = Starlette()
app = CORSMiddleware(app=app, allow_origins=["*"])

2. SessionMiddleware(会话管理)

提供基于签名 cookie 的 HTTP 会话管理:

from starlette.middleware.sessions import SessionMiddleware

middleware = [
    Middleware(
        SessionMiddleware,
        secret_key="your-secret-key",
        https_only=True
    )
]
关键特性:
  • 数据可读但不可篡改
  • 通过 request.session 字典接口访问
  • 支持会话过期时间配置

3. HTTPSRedirectMiddleware(HTTPS 重定向)

强制所有请求使用 HTTPS 协议:

from starlette.middleware.httpsredirect import HTTPSRedirectMiddleware

middleware = [
    Middleware(HTTPSRedirectMiddleware)
]

4. TrustedHostMiddleware(可信主机验证)

防止 HTTP 主机头攻击:

from starlette.middleware.trustedhost import TrustedHostMiddleware

middleware = [
    Middleware(
        TrustedHostMiddleware,
        allowed_hosts=['example.com', '*.example.com']
    )
]

5. GZipMiddleware(GZip 压缩)

自动压缩响应内容:

from starlette.middleware.gzip import GZipMiddleware

middleware = [
    Middleware(
        GZipMiddleware,
        minimum_size=1000,
        compresslevel=6
    )
]
注意事项:
  • 默认不压缩小于 500 字节的响应
  • 不会对已压缩内容进行二次压缩

自定义中间件开发

1. BaseHTTPMiddleware(基础 HTTP 中间件)

提供请求/响应接口的抽象类:

from starlette.middleware.base import BaseHTTPMiddleware

class CustomHeaderMiddleware(BaseHTTPMiddleware):
    async def dispatch(self, request, call_next):
        response = await call_next(request)
        response.headers['X-Custom'] = 'Value'
        return response
局限性:
  • 会影响上下文变量的传播
  • 不适用于需要精细控制 ASGI 消息的场景

2. 纯 ASGI 中间件

更底层的实现方式,完全遵循 ASGI 规范:

class PureASGIMiddleware:
    def __init__(self, app):
        self.app = app

    async def __call__(self, scope, receive, send):
        if scope["type"] != "http":
            return await self.app(scope, receive, send)
        
        # 预处理逻辑
        await self.app(scope, receive, send)
        # 后处理逻辑
优势:
  • 完全控制 ASGI 消息流
  • 无 BaseHTTPMiddleware 的限制
  • 更好的框架互操作性

中间件开发最佳实践

  1. 明确作用域:在中间件开头检查 scope["type"],确保只处理特定类型的请求
  2. 重用 Starlette 组件:利用 RequestHeaders 等高级抽象简化代码
  3. 保持无状态:避免在中间件实例中保存状态,应通过请求上下文传递数据
  4. 性能考虑:对于性能敏感的操作,考虑使用纯 ASGI 中间件

总结

Starlette 的中间件系统提供了从简单到复杂的多种实现方式,开发者可以根据需求选择合适的方法。无论是使用内置中间件快速实现常见功能,还是开发自定义中间件处理特定业务逻辑,Starlette 都提供了灵活而强大的工具集。

starlette The little ASGI framework that shines. 🌟 starlette 项目地址: https://gitcode.com/gh_mirrors/st/starlette

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

惠悦颖

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值