• flask笔记


    python中的web框架

    a:socket服务端 b:路由转发 c:模板渲染

    • Django(同步框架)
      • a:用的别人的,bc自己写的
    • Flask (同步框架)
      • a:用的别人的,b自己写的,c用的别人的(jinja2)
    • Tornado (异步框架)
      • abc都是自己写的
    • Sanic(可能会火,异步框架) 3.5以后支持,不支持windows

    实现了wsgi协议的web服务器

    wsgi协议(本质就是一个socket服务端):uwsgi,wsgiref

    java中的web服务器:tomcat,jboss

    cgi:通用网关协议,跟语言没有关系

    flask:基于Python开发,依赖jinja2模板(c用的别人的),和werkzeug wsgi服务器(本质是socket服务端)的微型框架,werkzeug wsgi服务器接收http请求,然后触发flask框架。

    werkzeug是一个工具包,里面实现了wsgi协议,werkzeug不是一个web服务器,也不是web框架,就是一个包,里面还有其他别的东西,可以作为web框架的底层库。

    flask的路由是基于装饰器的,装饰器的执行过程:如果装饰器语法糖没有括号(没有参数),就把装饰器下面的函数当做参数传给装饰器去执行,返回结果。如果有括号,先执行,然后返回一个函数fun的内存地址,接着把被装饰函数放入当做参数放入该函数fun中,返回结果。

    反向代理:找中介买房,多个客户端发送请求,反向代理(一个服务器)接收请求,决定请求要去哪个服务器。

    正向代理:找黄牛买票,翻墙,在客户端和服务端中间,接收客户端请求,让正向代理去访问请求的服务器

    读过的django源码,工作中碰到的问题,

    1、django request.post源码,碰到request.post出来的字典不能修改的问题

    • request.post是一个querydict, querydict继承MultiValueDict,而MultiValueDict继承字典,拥有字典的方法。multivaluedict的值是一个列表,形式例如:{'a':[1,2,3]},用get方法只能拿到第一个值1,用getlist拿到所有值。
    • querydict有一个最大特点:不支持修改,让中间件不能修改。
      • 源码:querydict的双下setitem写了个断言,如果修改了就抛出异常
      • 想修改,如何修改?request.post.dict一下,dict()方法会通过字典生成式返回一个新字典,通过新字典修改。

    2、自己写orm框架的时候,将字段对象存进mapping后,忘了删除原来名称空间中的字段名,如果不删,后面取字段值的时候会打印出一个field对象而不是一个值。

    2、元类object源码:

    • 元类里面有__ call __,这就是类可以调用的原因。对象要想调用,类中必须实现call, 类要想调用,元类实现call,
    • object没有 __ call __ 方法

    jinja2有没有处理XSS攻击?

    • 处理了,怎么处理的?html中的特殊符号,Markup('标签字符串') 通过函数传到模板页面处理

    jinja2模板语言

    • 支持函数加括号并传参,其他的用法完全通DTL
    • 有没有处理XSS攻击,处理了
      • 处理XSS攻击:html中的特殊符号
      • 模板中处理:{{ss|safe}}
      • 视图中用:ss = Markup(ss)

    请求响应:

    • request请求:
      • 多个请求同时发出,为什么没有乱
      • request.args GET请求的数据
      • request.form POST请求的数据
      • request.values GET和POST的数据
    • response响应
      • return 字符串
      • return render_template()
      • return redirect
      • return jsonify({})
      • make_response模块
        • obj = make_respones()
        • obj.set_cookie
        • obj.delete_cookie
        • obj.header['key'] = value

    session

    • cookie,session , token,jwt是什么?
      • 首先http无状态,无法保存用户状态,要用到登录保存状态怎么办,就需要一个东西将不同请求连接起来
      • 由于无状态性为了使域名下的所有页面连接起来,出现了cookie和session
      • session:服务端接收请求建立session,将session返回给客户端成为cookie。服务端需要存储session占用空间。服务器采用分布式或集群多服务器时,在多服务器的情况下,因为多服务器不共享session,不好确认当前用户是否登录。当然你也可以将所有session集中在一个服务器,但是不能完全达到负载均衡的效果。这时候就需要使用token。
      • cookie:存在于客户端的键值对,所有键值对都放在客户端,不安全,十万个用户的cookie都放在客户端费资源
      • token类似一个令牌,所有用户信息都被加密到token中,服务端收到token就能解密,知道是哪个用户。客户端每次访问都传递token,服务端解密token。服务端就不需要存储session占用空间,也可以解决分布式和集群的问题。
      • jwt就是一个加密字符串,作为验证信息在计算机之间进行传递。jwt是一个跨域验证的方案。
    • session使用前必须先设置一个秘钥:
      • app.secret_key = 'aasdfasdfasdf'
      • 放值取值:session['name'] = 'zjy'
    • cookie:
      • expires, max_age设置cookie超时时间
      • domain cookie生效的域名
      • path cookie生效的路径
      • secure=False 浏览器只能通过http回传cookie
      • httponly=False 只能http协议传输,无法通过js获取cookie,但不是绝对,底层抓包也能获取。
    • 第三方插件flask-session 干了什么事
      • 不想让session数据放在cookies中,把数据放在mysql中,redis中
      • app.session_interface = 我自己写的类
      • 必须实现save_session, open_session ,这就是插件干的事情。
        • save_session 就把session保存到了数据库中
    • 源码执行流程:
      • save_sesion:响应的时候,把session中的值加密序列化放到了cookie中,返回到浏览器
      • open_session:请求来了,从cookie中取出值,反解,再生成session对象,以后在视图函数中直接用session就可以了。
        • 判断session.modify

    闪现:flash, get_flashed_messages()

    • 设置值:flash
      • flash('超时错误', category='xxx'),
    • 取出值:get_flashed_messages(),一旦取过一次,在另一个视图函数中再取就没了
      • get_flashed_messages(category_filter=['xxx']), 如果filter里面是个['别的分类']就取不出来
    • 基于session,必须设置app.secret_key='aaasdfasdfa
    • 使用场景:在某个地方放一个值,过段时间需要取出来。在一个视图中设置值,在另一个视图中就可以拿到值。

    请求扩展:

    • 请求到来之前执行方法

      • @app.before_request

      •   @app.before_request
          def before_request():
              print('我来了')    
        
    • 请求执行完后执行方法

      •   @app.after_request
          def after_request(response)
          	print('我走了')
              return response
        
      • 执行顺序:先b后a, 如果before_request函数中有return,那么也会走after_request

      • before_request请求拦截后(也就是return),所有response都执行

    • before_first_request:服务器启动时执行,只执行这一次

    • teardown_request:一定会执行,即使出异常也会走

    • @app.errorhandler(404): 404的时候执行;errorhandler(500);

    中间件:

    • 跟Django中的不一样

    • flask中请求一旦到来,要执行app() —> 本质:执行的是app. __ call __ 方法 整个flask的入口

    •   class MyMiddleWare():
            def __init__(self, my_wsgi_app)
            	self.wsgi_app = my_wsgi_app
                
            def __call__(self, environ, start_response):
                print('之前执行一些东西')
                obj = self.wsgi_app(environ, stast_response)
                print('之后执行一些东西')
                return obj
                
        @app.route('/'):
        def index():
            print('ok')
            
        if __name__ == '__main__':
            app.wsgi_app = MyMiddleWare(app.wsgi_app) # 调用自己写的类的__call__方法
            app.run()
            
         #请求来了,执行app.__call__的本质执行的是:self.wsgi_app(environ, start_response)  
      

      补充:中间件是一个很大的概念,

      • web中间件:nginx,是在请求和服务器之间装了个东西,这个东西也叫中间件,nginx做请求的转发
      • 数据库中间件:orm,程序和数据库中间的东西
      • 消息队列中间件:两个程序之间要进行交互,需要用到消息队列中间件

    蓝图:

    • ​ 干什么用:分文件分目录,把代码全放在一个文件里面不就乱套了?所以要把文件功能分一分

    • 使用蓝图划分文件目录

      • 生成蓝图对象:在一个应用目录下面的 __ init __.py 里面写

        from flask import Flask, Blueprint
        	
        admin = Blueprint(
        	'admin',  # name, 产生app的时候只有一个import name
            __name__,  # import name
            template_folder='tamplates', # 指定admin这个蓝图用的模板和静态文件,如果不指定,用的是app的
            static_folder='static'
        )
        
      • 注册蓝图对象

        app.register_blueprint(admin, url_prefix='/admin')
        # url_prefix  url前缀,访问admin蓝图里面的路由需要加个前缀admin
        
      • 使用:

        #注册路由
        @admin.route('/index')
        def index():
            pass
        
        # 使用请求扩展
        @admin.before_request
        def before_request():
            pass
        
    • 蓝图项目目录实例:

      flask_project
      - flask_project
          - __ init __.py # 生成app,导入admin蓝图,导入user蓝图,注册admin蓝图,user蓝图
          - admin
              - __ init __ .py  # 注册蓝图,
              - static   # 存放静态文件
                  - 1.png
              - templates  # 存放模板文件
                  - index.html
              - views.py  # 导入蓝图,写view @admin.route()
          - user:同admin结构一样
      - run.py  # 导入app: from flask_project import app , app.run()
      
      
  • 相关阅读:
    Flex4 启动失败: 正在等待 Adobe Flash Player 连接调试器
    软件的黑盒和白盒分析方法
    PAIP.国内软件公司的现状及解决.txt
    软件逆向分析方法小结
    应用程序中主键ID生成与UUID
    JDK1.4下载 JRE1.4下载
    壳与软件保护
    数据恢复软件
    跨语言调用模块.TXT
    论文格式
  • 原文地址:https://www.cnblogs.com/KbMan/p/11487961.html
Copyright © 2020-2023  润新知