一、什么是中间件
(一)概念
中间件是一个函数,它在它在每个请求被特定的路径操作处理前,以及每个响应返回之前工作,所以:
- Request Middleware接收你应用程序的每一个请求
- 然后它可以对这个请求做一些操作,完成一些功能
- 处理完成后,Request Middleware将请求转发给Application
- Response Middleware接收到Application的响应
- 然后可以对响应做一些操作,完成一些功能
- 处理完成后,Response Middleware将响应进行返回给客户端
(二)使用
- 创建中间件
import time from fastapi import FastAPI, Request app = FastAPI() @app.middleware("http") async def add_process_time_header(request: Request, call_next): start_time = time.time() response = await call_next(request) process_time = time.time() - start_time response.headers["X-Process-Time"] = str(process_time) return response
上面创建了一个add_process_time_header的中间件,它的功能就是添加一个响应头,并且响应头的值就是处理这个响应的耗时时间。创建一个中间件你需要在
对应的函数顶部使用@app.middleware("http")装饰器,然后中间件函数需要接收两个参数:
- request
- callnext 这个函数将request传递给对应的路径操作,然后得到响应的response
上述的中间件函数就是在调用callnext前后分别计算出时间,也就是响应开始和结束的时间,最后将响应再加一个自定义的响应头,注意一般自定义的响应头以"X-"为前缀,与内置的进行区分。
- 使用中间件
... @app.get("/items/") async def get_items(): items = [ {"name": "apple", "price": "1.12"}, {"name": "pear", "price": "3.14"} ] return items ...
中间件是针对全局的,相当于一个全局的钩子,只要用同一个FastAPI实例,每一个请求都会走这个中间件。
二、常见中间件
(一)CORS Middleware
在使用前后台分离开发的过程中,跨域是避免不了的,所以该中间件针对的就是跨域资源共享。
from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware app = FastAPI() app.add_middleware( CORSMiddleware, allow_origins = [ "http://127.0.0.1", "http://127.0.0.1:8000", ], allow_credentials=True, allow_methods=["*"], allow_headers=["*"] ) @app.get("/items/") async def get_items(): items = [ {"name": "apple", "price": "1.12"}, {"name": "pear", "price": "3.14"} ] return items
这就添加了一个跨域的中间件,详细参数可参考源码:
class CORSMiddleware: def __init__( self, app: ASGIApp, allow_origins: typing.Sequence[str] = (), allow_methods: typing.Sequence[str] = ("GET",), allow_headers: typing.Sequence[str] = (), allow_credentials: bool = False, allow_origin_regex: str = None, expose_headers: typing.Sequence[str] = (), max_age: int = 600, ) -> None: ...
(二)HTTPSRedirectMiddleware
强制所有的请求必需是http或者wss协议。
from fastapi import FastAPI from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware app = FastAPI() app.add_middleware(HTTPSRedirectMiddleware) @app.get("/items/") async def get_items(): items = [ {"name": "apple", "price": "1.12"}, {"name": "pear", "price": "3.14"} ] return items
(三)TrustedHostMiddleware
强制所有的请求都设置了正确的Host头部信息,为了防止HTTP Host的头部攻击。
from fastapi import FastAPI from fastapi.middleware.trustedhost import TrustedHostMiddleware app = FastAPI() app.add_middleware( TrustedHostMiddleware, allowed_hosts=["*.example.com"] ) @app.get("/items/") async def get_items(): items = [ {"name": "apple", "price": "1.12"}, {"name": "pear", "price": "3.14"} ] return items
(四)GZipMiddleware
当请求的请求头中Accept-Encoding字段值包含“gzip”时,该中间件负责处理这个结果并进行响应。这个中间件将会处理标准以及流响应。
from fastapi import FastAPI from fastapi.middleware.gzip import GZipMiddleware app = FastAPI() app.add_middleware( GZipMiddleware, minimum_size=1000 ) @app.get("/items/") async def get_items(): items = [ {"name": "apple", "price": "1.12"}, {"name": "pear", "price": "3.14"} ] return items
如果不指定minimum_size的大小,将会使用其默认值500。