跳转至

高级中间件

在主教程中,您已经了解了如何向应用程序添加自定义中间件

随后您也学习了如何使用 CORSMiddleware 处理 CORS

本节我们将了解如何使用其他中间件。

添加 ASGI 中间件

由于 FastAPI 基于 Starlette 并实现了 ASGI 规范,您可以使用任何 ASGI 中间件。

只要遵循 ASGI 规范,中间件并不需要专门为 FastAPI 或 Starlette 开发。

通常,ASGI 中间件是期望接收一个 ASGI 应用作为第一个参数的类。

因此,在第三方 ASGI 中间件的文档中,它们可能会告诉您这样做:

from unicorn import UnicornMiddleware

app = SomeASGIApp()

new_app = UnicornMiddleware(app, some_config="rainbow")

但 FastAPI(实际上是 Starlette)提供了一种更简单的方法,可以确保内部中间件处理服务器错误和自定义异常处理程序正常工作。

为此,您可以使用 app.add_middleware()(如 CORS 示例中所示)。

from fastapi import FastAPI
from unicorn import UnicornMiddleware

app = FastAPI()

app.add_middleware(UnicornMiddleware, some_config="rainbow")

app.add_middleware() 接收一个中间件类作为第一个参数,以及要传递给中间件的任何其他参数。

集成中间件

FastAPI 包含多个用于常见用例的中间件,接下来我们将了解如何使用它们。

技术细节

对于接下来的示例,您也可以使用 from starlette.middleware.something import SomethingMiddleware

FastAPIfastapi.middleware 中提供了几个中间件,只是为了方便您(开发者)。但大多数可用的中间件直接来自 Starlette。

HTTPSRedirectMiddleware

强制所有传入请求必须使用 httpswss

任何到 httpws 的传入请求都将被重定向到安全方案。

from fastapi import FastAPI
from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware

app = FastAPI()

app.add_middleware(HTTPSRedirectMiddleware)


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

TrustedHostMiddleware

强制所有传入请求具有正确设置的 Host 头,以防止 HTTP 主机头攻击。

from fastapi import FastAPI
from fastapi.middleware.trustedhost import TrustedHostMiddleware

app = FastAPI()

app.add_middleware(
    TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]
)


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

支持以下参数:

  • allowed_hosts - 应允许作为主机名的域名列表。支持通配符域名,例如 *.example.com 用于匹配子域名。要允许任何主机名,可以使用 allowed_hosts=["*"] 或省略此中间件。
  • www_redirect - 如果设置为 True,对允许主机的非 www 版本的请求将被重定向到其对应的 www 版本。默认为 True

如果传入请求验证不正确,将发送 400 响应。

GZipMiddleware

处理任何在 Accept-Encoding 头中包含 "gzip" 的请求的 GZip 响应。

该中间件将处理标准和流式响应。

from fastapi import FastAPI
from fastapi.middleware.gzip import GZipMiddleware

app = FastAPI()

app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5)


@app.get("/")
async def main():
    return "somebigcontent"

支持以下参数:

  • minimum_size - 不对小于此最小大小(以字节为单位)的响应进行 GZip 压缩。默认为 500
  • compresslevel - 用于 GZip 压缩。它是一个从 1 到 9 的整数。默认为 9。较低的值压缩更快但文件较大,而较高的值压缩较慢但文件较小。

其他中间件

还有许多其他 ASGI 中间件。

例如:

要查看其他可用的中间件,请查看 Starlette 的中间件文档ASGI 资源列表