1豹休、
中間件是一個(gè)用來(lái)處理Django的請(qǐng)求和響應(yīng)的框架級(jí)別的鉤子磷瘤。它是一個(gè)輕量茵乱、低級(jí)別的插件系統(tǒng)茂洒,用于在全局范圍內(nèi)改變Django的輸入和輸出。每個(gè)中間件組件負(fù)責(zé)做一些特定的功能瓶竭。
由于其影響的是全局督勺,所以需要謹(jǐn)慎使用渠羞,使用不當(dāng)會(huì)影響性能。
說(shuō)的直白一點(diǎn)智哀,中間件可以幫助我們?cè)谝晥D函數(shù)執(zhí)行之前和執(zhí)行之后做一些額外的操作次询。
它的本質(zhì)是一個(gè)自定義類,類中定義了幾個(gè)方法瓷叫,Django框架會(huì)在請(qǐng)求的特定時(shí)間去執(zhí)行這些方法屯吊。
2、中間的五種方法:
process_request(self, request)
process_view(self, request, view_func, view_args, view_kwargs)
process_template_response(self, request, response)
process_exception(self, request, exception)
process_response(self, request, response)
以上方法的返回值可以是None摹菠,或者是一個(gè)HttpResponse對(duì)象盒卸,如果是None,則繼續(xù)按照django定義的規(guī)則向后繼續(xù)執(zhí)行次氨,如果是HttpResponse對(duì)象世落,則直接將改對(duì)象返回給用戶。
3糟需、自定義中間件:
from django.utils.deprecation import MiddlewareMixin
class MD1(MiddlewareMixin):
def process_request(self, request):
print("我是MD1的process_request方法")
def process_response(self, request, response):
print("我是MD1的process_response方法")
return response
class MD2(MiddlewareMixin):
def process_request(self, request):
print("我是MD2的process_request方法")
def process_response(self, request, response):
print("我是MD2的process_response方法")
return response
//settings.py
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',
# 自定義中間件(注意順序)
'untitled01.my_middlewares.MD1',
'untitled01.my_middlewares.MD2',
]
4、執(zhí)行流程:
請(qǐng)求到達(dá)中間件之后谷朝,先按照正序執(zhí)行每個(gè)注冊(cè)中間件的process_request方法洲押,如果process_request方法返回的值是None,就依次執(zhí)行圆凰;如果返回的值是HttpResponse對(duì)象杈帐,則不再執(zhí)行后面的process_request方法,而是執(zhí)行當(dāng)前對(duì)象中間件的process_response方法专钉,并將HttpResponse對(duì)象返回給瀏覽器挑童。
也就是說(shuō),如果MIDDLEWARE注冊(cè)了6個(gè)中間件跃须,執(zhí)行過(guò)程中站叼,第3個(gè)中間件返回了一個(gè)HttpResponse對(duì)象,那么第4, 5, 6中間件的process_request和process_response方法都不執(zhí)行菇民,而是順序執(zhí)行3, 2, 1中間件的process_response方法尽楔。
process_request方法都執(zhí)行完后,匹配路由第练,找到要執(zhí)行的視圖函數(shù)阔馋,先不執(zhí)行視圖函數(shù),而是先執(zhí)行中間件中的process_view方法娇掏,process_view方法返回None呕寝,則繼續(xù)按順序執(zhí)行,所有的process_view方法執(zhí)行完后婴梧,在執(zhí)行視圖函數(shù)下梢。如果中間件 3 的process_view方法返回了一個(gè)HttpResponse對(duì)象客蹋,則4, 5, 6的process_view以及視圖函數(shù)都不執(zhí)行了,而是直接從最后一個(gè)中間件怔球,也就是中間件 6 的process_response方法開(kāi)始倒序執(zhí)行嚼酝。
當(dāng)最后一個(gè)中間的process_request到達(dá)路由關(guān)系映射之后,返回到中間件1的process_view竟坛,然后依次往下闽巩,到達(dá)views函數(shù),最后通過(guò)process_response依次返回到達(dá)用戶
process_exception(self, request, exception)
當(dāng)views的函數(shù)中出現(xiàn)錯(cuò)誤時(shí)担汤,就會(huì)執(zhí)行process_exception方法
如果在中間中添加了process_exception方法涎跨,工作圖示為:
這樣當(dāng)用戶發(fā)起請(qǐng)求的時(shí)候到達(dá)中間件3的process_request之后會(huì)到達(dá)urls路由關(guān)系映射這里,如果匹配到了就會(huì)到中間件1的process_view,然后依次傳遞到中間件3的process_view,到達(dá)view函數(shù)崭歧。如果view函數(shù)中有報(bào)錯(cuò)隅很,則會(huì)從中間件3依次向上判斷每個(gè)中間件的process_exception是否能匹配到這個(gè)錯(cuò)誤信息,如果匹配到則直接返回到最后一個(gè)中間件率碾,這里即中間件3的process_response叔营,然后依次返回到用戶,如果沒(méi)有匹配到這個(gè)錯(cuò)誤則直接在頁(yè)面顯示錯(cuò)誤信息所宰。如果view函數(shù)中沒(méi)有錯(cuò)誤绒尊,則到中間3即最后一個(gè)中間件3的process_response,然后依次向上仔粥,傳到用戶
中間件之process_template_responseprocess
process_template_response(self,request,response)
只有當(dāng)views函數(shù)中返回的對(duì)象中具有render方法婴谱,是就會(huì)直接process_template_responseprocess
轉(zhuǎn)載:https://www.cnblogs.com/zhaof/p/6281541.html
5、常用內(nèi)置中間件:
緩存中間件:
django.middleware.cache.UpdateCacheMiddleware
django.middleware.cache.FetchFromCacheMiddleware
開(kāi)啟全站范圍的緩存躯泰。 如果開(kāi)啟了這些緩存谭羔,任何一個(gè)由Django提供的頁(yè)面將會(huì)被緩存,緩存時(shí)長(zhǎng)在CACHE_MIDDLEWARE_SECONDS中配置定義麦向。
會(huì)話中間件
django.contrib.sessions.middleware.SessionMiddleware
開(kāi)啟會(huì)話支持瘟裸,session支持中間件,加入這個(gè)中間件诵竭,會(huì)在數(shù)據(jù)庫(kù)中生成一個(gè)django_session的表景描。
通用中間件:
django.middleware.common.CommonMiddleware
通用中間件,會(huì)處理一些URL秀撇,比如baidu.com會(huì)自動(dòng)的處理成www.baidu.com超棺。比如/blog/111會(huì)處理成/blog/111/自動(dòng)加上反斜杠。
CSRF保護(hù)中間件
django.middleware.csrf.CsrfViewMiddleware
跨域請(qǐng)求偽造中間件呵燕。加入這個(gè)中間件棠绘,在提交表單的時(shí)候會(huì)必須加入csrf_token,cookie中也會(huì)生成一個(gè)名叫csrftoken的值,也會(huì)在header中加入一個(gè)HTTP_X_CSRFTOKEN的值來(lái)放置CSRF攻擊氧苍。
用戶授權(quán)中間件:
django.contrib.auth.middleware.AuthenticationMiddleware
他會(huì)在每個(gè)HttpRequest對(duì)象到達(dá)view之前添加當(dāng)前登錄用戶的user屬性夜矗,也就是你可以在view中通過(guò)request訪問(wèn)user。
消息中間件
django.contrib.messages.middleware.MessageMiddleware
展示一些后臺(tái)信息給前端頁(yè)面让虐。如果需要用到消息紊撕,還需要在INSTALLED_APPS中添加django.contrib.message才能有效。如果不需要赡突,可以把這兩個(gè)都刪除对扶。
XFrameOptionsMiddleware中間件
django.middleware.clickjacking.XFrameOptionsMiddleware
防止通過(guò)瀏覽器頁(yè)面跨Frame出現(xiàn)clickjacking(欺騙點(diǎn)擊)攻擊出現(xiàn)。