什么是中间件?中间件的作用,怎么使用中间件及应用场景
什么是中間件?中間件的作用,怎么使用中間件及應用場景
如果你想修改請求,例如被傳送到view中的HttpRequest對象。 或者你想修改view返回的HttpResponse對象,這些都可以通過中間件來實現。
可能你還想在view執行之前做一些操作,這種情況就可以用 middleware來實現。
Django默認的中間件:(在django項目的settings模塊中,有一個 MIDDLEWARE_CLASSES 變量,其中每一個元素就是一個中間件,如下圖)
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',# 'app01.mymid.MyMid1',# 'app01.mymid.MyMid2', ]請求進來是自上而下,通過反射找到類,用for循環來執行,可以自定義中間件,但是也要寫在MIDDLEWARE中,可以在app01下創建一個mymid.py文件來寫我們自定義的中間件
每一個中間件都有具體的功能
三、自定義中間件
中間件可以定義五個方法,分別是:(主要的是process_request和process_response)
1、process_request(self,request)2、process_view(self, request, callback, callback_args, callback_kwargs)3、process_template_response(self,request,response)4、process_exception(self, request, exception)5、process_response(self, request, response)以上方法的返回值可以是None或一個HttpResponse對象,如果是None,則繼續按照django定義的規則向后繼續執行,如果是HttpResponse對象,則直接將該對象返回給用戶。
詳細用法見下方:
1、process_request和process_response
當用戶發起請求的時候會依次經過所有的的中間件,這個時候的請求時process_request,最后到達views的函數中,views函數處理后,在依次穿過中間件,這個時候是process_response,最后返回給請求者。
上述截圖中的中間件都是django中的,我們也可以自己定義一個中間件,我們可以自己寫一個類,但是必須繼承MiddlewareMixin
第一步:導入
from django.utils.deprecation import MiddlewareMixin第二步:自定義中間件
from django.utils.deprecation import MiddlewareMixin# from django.shortcuts import HttpResponseclass Md1(MiddlewareMixin): def process_request(self,request):print("Md1請求") def process_response(self,request,response):print("Md1返回")return responseclass Md2(MiddlewareMixin):def process_request(self,request):print("Md2請求")#return HttpResponse("Md2中斷")def process_response(self,request,response):#print("Md2返回")return response第三步:在view中定義一個視圖函數(index)
def index(request):print("view函數...")return HttpResponse("OK")第四步:在settings.py的MIDDLEWARE里注冊自己定義的中間件
運行結果:
Md1請求# Md2請求# view函數...# Md2返回# Md1返回#**注意:**如果當請求到達請求2的時候直接不符合條件返回,即return HttpResponse(“Md2中斷”),程序將把請求直接發給中間件2返回,然后依次返回到請求者,結果如下:
返回Md2中斷的頁面,后臺打印如下:
Md1請求# Md2請求# Md2返回# Md1返回#流程圖如下:
由此總結一下:
多個中間件中的process_response方法是按照MIDDLEWARE中的注冊順序倒序執行的,也就是說第一個中間件的process_request方法首先執行,而它的process_response方法最后執行,最后一個中間件的process_request方法最后一個執行,它的process_response方法是最先執行。
2、process_view
process_view(self, request, view_func, view_args, view_kwargs)
該方法有四個參數
request是HttpRequest對象。
view_func是Django即將使用的視圖函數。 (它是實際的函數對象,而不是函數的名稱作為字符串。)
view_args是將傳遞給視圖的位置參數的列表(無名分組分過來的值).
view_kwargs是將傳遞給視圖的關鍵字參數的字典(有名分組分過來的值)。 view_args和view_kwargs都不包含第一個視圖參數(request)。
Django會在調用視圖函數之前調用process_view方法。
它應該返回None或一個HttpResponse對象。 如果返回None,Django將繼續處理這個請求,執行任何其他中間件的process_view方法,然后在執行相應的視圖。 如果它返回一個HttpResponse對象,Django不會調用適當的視圖函數。 它將執行中間件的process_response方法并將應用到該HttpResponse并返回結果。
process_view(self, request, callback, callback_args, callback_kwargs) from django.utils.deprecation import MiddlewareMixin from django.shortcuts import HttpResponseclass Md1(MiddlewareMixin):def process_request(self,request):print("Md1請求")#return HttpResponse("Md1中斷")def process_response(self,request,response):print("Md1返回")return responsedef process_view(self, request, callback, callback_args, callback_kwargs):print("Md1view")class Md2(MiddlewareMixin):def process_request(self,request):print("Md2請求")return HttpResponse("Md2中斷")def process_response(self,request,response):print("Md2返回")return responsedef process_view(self, request, callback, callback_args, callback_kwargs):print("Md2view")運行結果:
Md1請求# Md2請求# Md1view# Md2view# view函數...# Md2返回# Md1返回#下圖進行分析上面的過程:
當最后一個中間的process_request到達路由關系映射之后,返回到中間件1的process_view,然后依次往下,到達views函數,最后通過process_response依次返回到達用戶。
process_view可以用來調用視圖函數:
class Md1(MiddlewareMixin):def process_request(self,request):print("Md1請求")#return HttpResponse("Md1中斷")def process_response(self,request,response):print("Md1返回")return responsedef process_view(self, request, callback, callback_args, callback_kwargs):# return HttpResponse("hello")response=callback(request,*callback_args,**callback_kwargs)return response運行結果:
Md1請求# Md2請求# view函數...# Md2返回# Md1返回#注意:process_view如果有返回值,會越過其他的process_view以及視圖函數,但是所有的process_response都還會執行。
3、process_exception
process_exception(self, request, exception)
該方法兩個參數:
一個HttpRequest對象
一個exception是視圖函數異常產生的Exception對象。
這個方法只有在視圖函數中出現異常了才執行,它返回的值可以是一個None也可以是一個HttpResponse對象。如果是HttpResponse對象,Django將調用模板和中間件中的process_response方法,并返回給瀏覽器,否則將默認處理異常。如果返回一個None,則交給下一個中間件的process_exception方法來處理異常。它的執行順序也是按照中間件注冊順序的倒序執行。
process_exception(self, request, exception)實例如下:
class Md1(MiddlewareMixin):def process_request(self,request):print("Md1請求")#return HttpResponse("Md1中斷")def process_response(self,request,response):print("Md1返回")return responsedef process_view(self, request, callback, callback_args, callback_kwargs):# return HttpResponse("hello")# response=callback(request,*callback_args,**callback_kwargs)# return responseprint("md1 process_view...")def process_exception(self,request,exception):print("md1 process_exception...")class Md2(MiddlewareMixin):def process_request(self,request):print("Md2請求")# return HttpResponse("Md2中斷")def process_response(self,request,response):print("Md2返回")return responsedef process_view(self, request, callback, callback_args, callback_kwargs):print("md2 process_view...")def process_exception(self,request,exception):#只有報錯了才會執行exceptionprint("md1 process_exception...")運行結果:
Md1請求 Md2請求 md1 process_view... md2 process_view... view函數...Md2返回 Md1返回流程圖如下:
當views出現錯誤時:
將md2的process_exception修改如下:
def process_exception(self,request,exception):print("md2 process_exception...")return HttpResponse("error")運行結果:
Md1請求# Md2請求# md1 process_view...# md2 process_view...# view函數...# md2 process_exception...# Md2返回# Md1返回#4、process_template_response(self,request,response)
該方法對視圖函數返回值有要求,必須是一個含有render方法類的對象,才會執行此方法
class Test:def __init__(self,status,msg):self.status=status#self.msg=msg#def render(self):#import json#dic={'status':self.status,'msg':self.msg}#return HttpResponse(json.dumps(dic)) def index(response):#return Test(True,'測試')四 中間件應用場景
1、做IP訪問頻率限制
某些IP訪問服務器的頻率過高,進行攔截,比如限制每分鐘不能超過20次。
2、URL訪問過濾
如果用戶訪問的是login視圖(放過)
如果訪問其他視圖,需要檢測是不是有session認證,已經有了放行,沒有返回login,這樣就省得在多個視圖函數上寫裝飾器了!
作為延伸擴展內容,有余力的同學可以嘗試著讀一下以下兩個自帶的中間件:
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',總結
以上是生活随笔為你收集整理的什么是中间件?中间件的作用,怎么使用中间件及应用场景的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最好用的临时邮箱网站
- 下一篇: php开源文档共享,几款常见的PHP开源