中间件

简介

中间件的本质就是一个python 类,中间件的本质是一个python类实现的装饰器,装饰器分为两种一种为函数实现,另一种为类实现,装饰器详情见:https://www.cnblogs.com/arvin-feng/p/11108799.html

中间件:是一个轻量级的,底层的插件,可以介入Django的请求和相应过程(面向切面编程)

面向切面编程(AOP)

面向切面编程(Aspect Oriented Programming)简称AOP。AOP的主要实现目的是针对业务处理过程中的切面进行提取,它所面对的是处理过程中的某个步骤或阶段,以获得逻辑过程中各部分之间低耦合的隔离效果。

面向切面编程有两个核心概念,1是切点,切面,也就是在哪切  2是通过切面可以获得什么

中间件的可切入点:

如图中红字所示,python在四个位置上内置了切点,我们除了关注这些切点,还要关注这些切面里面有什么

切入函数

  • __init__:没有参数,服务器响应第一个请求的时候自动调用,用户确定是否启用该中间件
  • process_request(self,request):在执行视图前被调用,每个请求上都会调用,不主动进行返回或返回HttpResponse对象

    • 不主动进行返回指的是返回值为none,这样会继续执行后续的视图操作,而返回HttpResponse则是将这里切面切开。
    • 我们在处理之前通过这个切面可以做一遍校验,检查request请求和不和规,如果不合格,直接拒绝。
  • process_view(self,request, callback, callback_args, callback_kwargs):调用视图之前执行,每个请求都会调用,不主动进行返回或返回HttpResponse对象
  • process_template_response(self,request,response):在视图刚好执行完后进行调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象
  • process_response(self,request,response):所有响应返回浏览器之前调用,每个请求都会调用,不主动进行返回或返回HttpResponse对象
  • process_exception(self,request,exception):当视图抛出异常时调用,不主动进行返回或返回HttpResponse对象

    • 视图出错就会报出5xx服务器内部错误,这种错误是程序员最丢人的错误,通过这个切面我们可以全局捕获5xx错误,提高容错率。

    中间件功能

  • 实现统计功能

    • 统计IP
    • 统计浏览器,使用IE还是谷歌浏览器
  • 实现权重控制

    • 黑名单
    • 白名单
  • 权限设计
  • 实现反爬

    • 反爬虫

      • 十秒之内只能搜索一次
    • 实现频率控制(淘宝刷新30次就会出题目证明你是个人)

    实验:自定义中间件       process_request

    前面的概念看了很懵批,莫慌,看看下面的实验,搞不好就能顿悟。

    自定义中间件流程

  1. 在工程目录下创建middleware目录
  2. 目录中创建一个python文件

    • 中间件是一个python文件
  3. 在python文件中导入中间件的基类

      from django.utils.deprecation import MiddlewareMixin

  1. 在类中根据功能需求,创建切入需求类,重写切入点方法(自定义的中间件系统不承认,需要伪装成中间件,所以需要继承自系统中间件)

  class LearnAOP(MiddlewareMixin):
  def process_request(self,request):
  print('request的路径',request.GET.path)

  1. 启用中间件,在settings中进行配置,MIDDLEWARE中添加

middleware.文件名.类名

实验1   

1./2.   创建目录,创建python文件
image.png
3.
在新建的py文件中添加类来继承系统的中间件

from django.utils.deprecation import MiddlewareMixin

class HelloMiddle(MiddlewareMixin):  # Mixin 是使混合的意思,代表基类,多继承时一般以mixin结尾
    pass

4.
注册settings,找到middleware,添加:

MIDDLEWARE = [
    'middleware.LearnMiddle.HelloMiddle',  # .指的是路径的"/",目录,文件名.类
    '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',
]

5.写切点,获取切面
我们将刚才新建的类补全

from django.utils.deprecation import MiddlewareMixin


class HelloMiddle(MiddlewareMixin):  # Mixin 是使混合的意思
    
    def process_request(self, request):
        print(request.META.get('REMOTE_ADDR'))# 用来获得访问者的ip地址

6.新建路由页面测试中间件
urls:

 url('^home/', views.home, name='home'),

views:

def home(request):
    return HttpResponse('HOME')

我们访问home

接着我们看到了IP地址,这样我们就可以进行数据分析,根据各种IP地址分析爱上这个网站的都是哪个区域的人,哪个国家的人,哪个城市等等等等

所以中间件可以实现统计功能。

实验2

做一个抢手机的网站,抢优惠券的时候电脑评估你的个人信息,有可能觉得你不是优质客户,所以别人能抢到而你却抢不到.

1.新建url:

url('^getphone/', views.get_phone, name='get_phone'),

2.新建views

def get_phone(request):
    if random.randrange(100) > 95:
        return HttpResponse('恭喜你抢到小米10pro')
    return HttpResponse('不好意思正在排队嗷')

3.访问网页

3.添加中间件
我们不对ivews做任何修改,而是通过中间件来实现抢手机的概率想要多少就是多少。
修改LearnMiddleware.py文件:
(白名单)

class HelloMiddle(MiddlewareMixin):  # Mixin 是使混合的意思

    def process_request(self, request):
        print(request.META.get('REMOTE_ADDR'))
        
        ip = request.META.get('REMOTE_ADDR')
        if ip == '127.0.0.1':
            return HttpResponse('恭喜你免费获得小米10pro')


可以看到一定中奖

我也可以避嫌,给自己一个加权权重

        if request.path == '/app/getphone/':
            if ip == '127.0.0.1':
                if random.randrange(100) > 20:
                    return HttpResponse('恭喜你免费获得小米10pro')

这样就可以让自己变成80%+(0.2*0.05)的中奖概率,而其他人只有5%

实验3

现在有个撸羊毛的家伙顾某,此人酷爱上京东撸羊毛,今天买了个电脑玩了6天(7天无理由退款)给退货了,明天又买了张显卡挖两天框矿就退货,此后总是买了退,这人就不能让他拿到满100减99元的优惠券,我们就要拉进黑名单。

urls:

    url('^getticket/', views.get_ticket, name='get_ticket'),

views:

def get_ticket(request):
    return HttpResponse('已抢到优惠券')

LearnMiddleware.py:
(黑名单)

        if request.path == '/App/getticket/':
            if ip.startswith('192.168.1.1'): #  以结尾1开头的ip地址都显示被抢光
                return HttpResponse('已抢光')

这样就拉入了黑名单

实验二实验三体现了权重控制

实验4

我们要限制下载的频率,间隔10秒
urls:

url('^search/', views.search, name='search'),

views:

def search(request):
    return HttpResponse('搜索到的种子资源')

想要修改频率,我们可以在views函数中修改,但是不提倡

因为程序讲究低耦合,搜索功能就是单纯的搜索,但是还有一些功能的比如频率限制,这两个功能要区分开,不能混和写,这两个功能应该是独立的,通过某种方式,将二者组合在一起

LearnMiddleware.py:


        if request.path == '/App/search/':
            result = cache.get(ip)  # 这里获取缓存中的ip地址
            if result:  # 如果缓存存在这个IP地址,就会频繁
                return HttpResponse('您访问的太频繁,请稍后再访问')
            cache.set(ip, ip, timeout=10)  # 如果缓存没有就需要保存ip地址10s
最后修改:2024 年 03 月 13 日
如果觉得我的文章对你有用,请随意赞赏