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