django的中间件
MiddleWare,是 Django 请求/响应处理的钩子框架。它是一个轻量级的、低级的“插件”系统,用于全局改变 Django 的输入或输出。【输入指代的就是客户端像服务端django发送数据,输出指代django根据客户端要求处理数据的结果返回给客户端】
钩子就是编程开发的一个术语,hook,钩子可以理解为一段代码(要么是类,要么是函数),它的作用就类似日常生活中墙上的钩子,不需要的时候,挂在墙上不会占用房子的空间,但是需要的时候我们可以把一些物件挂在上面。
这种中间件在平时不使用情况下不会耗费任何的性能,如果编写了中间件以后,可以在特定的条件下,全局执行!!
文档: https://docs.djangoproject.com/zh-hans/2.2/topics/http/middleware/
内置中间件
django框架内部声明了很多的中间件,这些中间件有着各种各种的用途,有些没有被使用,有些被默认开启使用了。
而被开启使用的中间件,都是在settngs.py的MIDDLEWARE中注册使用的。
# 中间件列表 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # 安全监测相关的中间件,防止页面过期, js跨站脚本攻击xss 'django.contrib.sessions.middleware.SessionMiddleware', # session加密和读取和保存session相关 'django.middleware.common.CommonMiddleware', # 通用中间件,用于给url进行重写 'django.middleware.csrf.CsrfViewMiddleware', # 防止网站遭到csrf攻击的 'django.contrib.auth.middleware.AuthenticationMiddleware', # 用户认证的中间件 'django.contrib.messages.middleware.MessageMiddleware', # 错误提示信息的中间件【提示错误信息,一次性提示】 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 用于防止点击劫持攻击的 iframe标签 ]
自定义中间件
django中提供了2种不同的中间件声明方式.主要在django1.9或者2.0出现
函数式中间件
def simple_middleware(get_response): # 自定义中间件 def middleware(request): # Code to be executed for each request before # the view (and later middleware) are called. print("--------------视图执行之前---------------") # 记录访问用户记录的信息,识别判断黑名单,白名单,判断用户是否登录, 判断用户是否拥有访问权限..... # 视图执行之前 response = get_response(request) # 视图调用 # 视图执行之后 print("-------------视图执行以后----------------") # 记录用户的操作历史,访问历史,日志记录, 资源的回收... return response return middleware
下面注册中间件
# 中间件列表 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', 'middle.simple_middleware', # 没有特殊要求,一般自己定义的中间件写在最后 ]
因为中间件一旦注册了以后, 会在全局生效, 所以我们访问任何一个视图都可以看到中间件执行的过程.
from django.http.response import HttpResponse class HomeView(View): def get(self,request): print( "---------------视图执行了---------------" ) return HttpResponse("ok")
最终,访问视图,效果如下:
和函数式的中间件一样,我们一般都会保存在一个独立的文件中.把所有的中间件按不同的业务存放在一块,.
def simple_middleware(get_response): # 自定义中间件 def middleware(request): # Code to be executed for each request before # the view (and later middleware) are called. print("--------------视图执行之前---------------") # 记录访问用户记录的信息,识别判断黑名单,白名单,判断用户是否登录, 判断用户是否拥有访问权限..... # 视图执行之前 response = get_response(request) # 视图执行之后 print("-------------视图执行以后----------------") # 记录用户的操作历史,访问历史,日志记录, 资源的回收... return response return middleware from django.utils.deprecation import MiddlewareMixin from django.http.response import HttpResponse class CustomMiddleware(MiddlewareMixin): """中间件类""" def process_request(self,request): # 方法名是固定的,该方法会在用户请求访问路由解析完成以后,调用视图之前自动执行 print("1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法") # 用途:权限,路由分发,cdn,用户身份识别,白名单,黑名单... # 注意,此方法不能使用return,使用则报错!!! def process_view(self,request,view_func, view_args, view_kwargs): # 用途:进行缓存处理,识别参数,根据参数查询是否建立缓存 print("2. process_view在视图接受了参数以后,没有执行内部代码之前") # 可以返回response对象, 如果返回response对象以后,则当前对应的视图函数将不会被执行 # return HttpResponse("ok") # 也可以不返回response,则默认返回None,django就会自动执行视图函数 def process_response(self,request,response): print("4. process_response在视图执行以后,才执行的") # 用途:记录操作历史, 记录访问历史,修改返回给客户端的数据, 建立缓存 # 必须返回response对象,否则报错!! return response def process_exception(self, request, exception): print(exception) # 用途:进行异常的处理或者记录错误日志 print("5. process_exception会在视图执行发生异常的时候才会执行") def process_template_response(self,request, response): # 用途:建立页面缓存 print("6. process_template_response只有在视图调用了模板以后,才会执行!!!") return response
中间件类和函数式中间件的注册方式雷同,也是在setting.py中直接注册.
# 中间件列表 MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', # 安全监测相关的中间件,防止,页面过期, js跨站脚本攻击xss 'django.contrib.sessions.middleware.SessionMiddleware', # session加密和读取和保存session相关 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', # 'middle.simple_middleware', 'middle.CustomMiddleware', ]
从上面不管是函数式中间件还是中间件类,他们的执行顺序都是类似的.也就是部分的方法在视图执行之前执行,部分方法是在视图执行之后执行的.
终端执行结果:
# 没有异常 1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法 2. process_view在视图接受了参数以后,没有执行内部代码之前 视图执行了!!! 4. process_response在视图执行以后,才执行的 # 视图中有异常 1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法 2. process_view在视图接受了参数以后,没有执行内部代码之前 视图执行了!!! 5. process_exception会在视图执行发生异常的时候才会执行: error 4. process_response在视图执行以后,才执行的
如果多个中间件一起执行,效果如下
1-1 视图执行之前的代码 # 【simple_middle】 1. process_request在路由解析以后,产生request对应, 视图执行之前,会执行这个方法 # 【CustomMidleWare】 2. process_view在视图接受了参数以后,没有执行内部代码之前# 【CustomMidleWare】 视图执行了!!!# 【视图代码】 4. process_response在视图执行以后,才执行的 # 【CustomMidleWare】 1-2 视图执行之后的代码 # 【simple_middle
从上面的打印结果可以看到,中间件是包含了视图代码的执行,所以中间件的执行顺序,是回环式执行