(19)中间件
"中间件"是一个函数,它在每个请求被特定的路径操作处理之前,以及在每个响应返回之前工作.
-
它接收你的应用程序的每一个请求.
-
然后它可以对这个请求做一些事情或者执行任何需要的代码.
-
然后它将请求传递给应用程序的其他部分 (通过某种路径操作).
-
然后它获取应用程序生产的响应 (通过某种路径操作).
-
它可以对该响应做些什么或者执行任何需要的代码.
-
然后它返回这个 响应
要创建中间件你可以在函数的顶部使用装饰器@app.middleware("http")
1. 中间件实现
from fastapi import FastAPI, Request
import uvicorn
app = FastAPI()
@app.middleware('http')
async def m2(request: Request, call_next):
# 请求代码块
print('m2 request m2请求')
response = await call_next(request)
# 响应代码块
response.headers['author'] = 'yuan'
print('m2 response m2响应')
return response
@app.middleware('http')
async def m1(request: Request, call_next):
"""
中间件用于处理HTTP请求和响应。
在请求处理之前,打印请求开始的信息。
在请求处理之后,打印响应结束的信息。
参数:
- request: Request对象,表示传入的HTTP请求。
- call_next: 一个协程函数,用于执行下一个中间件或最终的请求处理函数。
返回:
- response: 响应对象,表示处理后的HTTP响应。
"""
# 请求代码块
print('m1 request m1请求')
response = await call_next(request)
# 响应代码块
print('m1 response m1响应')
return response
@app.get('/user')
async def user():
print('user函数执行')
return {'user': 'current user'}
@app.get('/item/{item_id}')
async def item(item_id: int):
print('item函数执行')
return {'item_id': item_id}
if __name__ == '__main__':
uvicorn.run('main:app', host='127.0.0.1', port=8080, reload=True, workers=1)
打印看下:
2. 中间件的用处
我们举几个例子看下:
(1)拦截黑名单
@app.middleware('http')
async def m1(request: Request, call_next):
# 请求代码块
print('m1 request m1请求')
if request.client.host in ['127.0.0.1', ]: # 拦截请求:黑名单
return Response(content='Blacklist Users')
response = await call_next(request)
# 响应代码块
print('m1 response m1响应')
return response
添加这块代码的时候,我们发现连测试文档都进不去了
(2)限制访问某路由
@app.middleware('http')
async def m1(request: Request, call_next):
# 请求代码块
print('m1 request m1请求')
if request.url.path in ['/user']:
return Response(content='您无权限访问')
response = await call_next(request)
# 响应代码块
print('m1 response m1响应')
return response
我们测试另一个路由的时候,是正常的
(3)给Response headers
加字段
@app.middleware('http')
async def m1(request: Request, call_next):
# 请求代码块
print('m1 request m1请求')
response = await call_next(request)
# 响应代码块
# 给`Response headers`加字段
response.headers['author'] = 'yuan'
print('m1 response m1响应')
return response