Sanic middleware – 中介軟體

veelion發表於2019-04-03

中介軟體是在伺服器接受請求之前或之後執行的函式。它們用於修改傳遞給路由處理函式的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.com 原創,沒有猿人學授權,請勿以任何形式轉載。***

相關文章