高级中间件¶
在主教程中,你已经了解了如何为应用添加自定义中间件。
同时,你还学习了如何通过 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。
FastAPI 在 fastapi.middleware 中提供了一些中间件,仅仅是为了方便开发者使用。但大多数可用的中间件直接来源于 Starlette。
HTTPSRedirectMiddleware¶
强制所有传入请求必须使用 https 或 wss 协议。
任何指向 http 或 ws 的传入请求都将被重定向到安全模式。
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 Awesome 列表。