[Django]中间件中5个常用方法与内置中间件剖析

1 中间件的常用代码

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import HttpResponse

class MyMiddleware(MiddlewareMixin):
    # 重写了init方法
    def __init__(self,get_response=None):
        super().__init__(get_response)
        print('init_mymiddleware')
    # 1.请求进入中间件后,运行第一个方法
    def process_request(self,request):
        # 返回HttpResponse|None
        pass
    # 2.执行完process_request,就会执行process_view,func为视图函数,
    # 所以func(request)就相当于执行了视图函数
    def process_view(self,request,func,*args,**kwargs):
        print('process_view')
        response = func(request)
        return response
    # 3.如果返回的Response是渲染后的模板,对调用process_template_response方法(但我测试返回啥response都不执行这个方法)
    def process_template_response(self,request,response):
        return response
    # 4.如果返回的Response是非模板渲染的结果,会调用process_response(我的测试结果是无论返回什么response,都执行process_response)
    def process_response(self,request,response):
        return response
    # 5.当调用视图函数出现异常或返回Response异常,调用的函数
    def process_exception(self,request,exception):
        return HttpResponse('error')

2 解析每个方法

2.1 init方法要调用父类方法

init方法在启动服务的时候执行一次

2.2 process_request(self,request)

  1. 请求进入中间件后,第一个执行的方法
  2. 返回值有两个:Response|None
    • 返回Response,不会再执行视图函数,而是调到process_response方法(此处有坑,最后说)
    • 返回None,或者不return,继续运行

2.3 process_view(self,request,func,*args,**kwargs)

  1. 运行完process_request后,就运行这个
  2. func是要执行的视图函数,所以:response = func(request) return response,可以得到视图函数的结果
    • 如果调用了func(request)方法,如果不return response的话,视图函数还会执行一次,所以要不就不调用,调用就return
    • 如果手动调用了func(request)方法,视图函数中的异常不会被process_exception(self,request,exception)接收

2.4 process_response(self,request,response)

  1. 每次返回response的时候必经的方法
  2. 必须return 一个 response,否则页面显示啥?

2.5 process_template_response(self,request,response)

官方说当视图函数的返回结果是return render(request,‘xxx.html’,context)的时候,走process_template_response包装返回的响应,但我测试,发现不会调用这个方法,模板渲染返回的response也会调用process_response这个方法,可能是版本的问题吧,另外这个方法使用的情况真的比较少

2.6 process_exception(self,request,exception)

  1. 视图函数中出现了异常,接受异常的信息
  2. 但如果视图函数时通过上面所说,在process_view中手动调用了func(request),则process_exception方法不会被调用接收异常信息

3 Django都有啥内置的中间件

我使用的Django的版本是2.2,如果和你的中间件有区别,还请查看官方手册(虽然那玩意不怎么好看)

3.1 内置中间件

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',
]

3.2 SecurityMiddleware

安全中间件,比如过滤xss脚本

3.3 SessionMiddleware

会话中间件,Session支持中间件,加入这个中间件,会在数据库中生成django_session这个表(如果你用MySQL去存session的话)

3.4 CommonMiddleware

通用中间件,一般是处理URL
比如:www.pyheishou.com/index --> 处理成www.pyheishou.com/index/

3.5 CsrfViewMiddleware

CSRF保护中间件,防止跨域攻击,加上这个中间件,POST表单提交的时候必须加入{% csrf_token %},否则就403

3.6 AuthenticationMiddleware

授权中间件,在request中添加了user,为当前登录的用户,这个在Admin后台管理中体现的尤为明显

3.7 MessageMiddleware

消息中间件(没有过,不敢瞎说)
据说是显示后台信息给前端,需要把这个开启
开启消息中间件:

  1. 中间件中添加MessageMiddleware
  2. INSTALLED_APPS中添加django.contrib.message
  3. 这两个默认就已经开启了,一般咱们不动他就好

3.8 XFrameOptionsMiddleware

防止通过浏览器页面跨Frame出现clickjacking(欺骗点击)攻击出现

4 中间件的执行

4.1 执行顺序

在这里插入图片描述

4.2 在process_request方法中如果return Response?

在这里插入图片描述
会跳转到当前中间件对应的process_exception,所以不会执行之前的那些process_response了

5 中间件的引入


列表中中间件的位置,决定了他的执行位置

猜你喜欢

转载自blog.csdn.net/kzl_knight/article/details/90692758