Sanic middleware – 中间件

Sanic教程 2019-04-03 22:45:27 阅读(24093) 评论(0)

中间件是在服务器接受请求之前或之后执行的函数。它们用于修改传递给路由处理函数的request,或是由处理函数生成的response对象。

Sanic middleware - 中间件

中间件类型

中间件有两种类型:requestresponse,都是通过@app.middleware修饰器来声明的,以修饰器的字符串参数requestresponse来表示这两种类型。

  • 请求中间件只接受request对象作为参数。
  • 响应中间件同时接受requestresponse两个对象作为参数。

下面是一个最简单的中间件的例子,它没有改变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_keyrequest对象增加了一个新的键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就不会被执行。

猿人学banner宣传图

我的公众号:猿人学 Python 上会分享更多心得体会,敬请关注。

***版权申明:若没有特殊说明,文章皆是猿人学 yuanrenxue.con 原创,没有猿人学授权,请勿以任何形式转载。***

说点什么吧...