中间件是在服务器接受请求之前或之后执行的函数。它们用于修改传递给路由处理函数的request
,或是由处理函数生成的response
对象。
中间件类型
中间件有两种类型:request和response,都是通过@app.middleware
修饰器来声明的,以修饰器的字符串参数request
或response
来表示这两种类型。
- 请求中间件只接受
request
对象作为参数。 - 响应中间件同时接受
request
和response
两个对象作为参数。
下面是一个最简单的中间件的例子,它没有改变request和response,只是打印了信息:
@app.middleware('request')
async def print_on_request(request):
print("I print when a request is received by the server")
@app.middleware('response')
async def print_on_response(request, response):
print("I print when a response is returned by the server")
修改request或response
中间件可以修改作为参数传递的request或response,但不需要返回它们,参见下面的例子:
from sanic import Sanic
from sanic import response
app = Sanic(__name__)
@app.middleware('request')
async def add_key(request):
# Add a key to request object like dict object
request['foo'] = 'bar'
@app.middleware('response')
async def custom_banner(request, response):
response.headers["Server"] = "Fake-Server"
@app.middleware('response')
async def prevent_xss(request, response):
response.headers["x-xss-protection"] = "1; mode=block"
@app.route('/')
async def home(request):
return response.text(request['foo'])
app.run(host="127.0.0.1", port=8888, debug=True)
上面的代码将按顺序应用3个中间件。第一个中间件add_key给request
对象增加了一个新的键foo
,这样可以工作是因为request
对象可以像字典那样被操作。
第二个中间件custom_banner修改了HTTP响应的头,把Server
设置成Fake-Server
。
最后一个中间件prevent_xss添加了响应头以防止跨站点脚本(XSS)攻击。
response类型的中间件在路由处理函数(比如,本例中的home()
返回response
后被调用。
使用curl
访问上面代码的链接:
curl -i http://127.0.0.1:8888
我们可以看到:
HTTP/1.1 200 OK
Connection: keep-alive
Keep-Alive: 5
x-xss-protection: 1; mode=block
Server: Fake-Server
Content-Length: 3
Content-Type: text/plain; charset=utf-8
bar
提前响应
这里的“提前”是指中间件直接返回HTTPResponse
对象,这时请求将停止处理并返回response。如果这发生在request类型的中间件,路由处理函数将不会被调用。返回response将阻止后续的中间件继续执行。
比如:
@app.middleware('request')
async def halt_request(request):
return text('I halted the request')
@app.middleware('response')
async def halt_response(request, response):
return text('I halted the response')
因为中间件halt_request
返回了Response
对象,其后续的中间件halt_response
就不会被执行。

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。
***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***
说点什么吧...