标签:协议 推荐 load host nic 支持 method lte 规则
flask框架 用Python做Web开发的三大框架特点 Django 主要特点是大而全,集成了很多的组件,例如:Admin Form Model等,不管你用不用的到,他都会为 你提供,通常用于大型Web应用,由于内部组件足够强大,所以使用Django可以做到一气呵成, Django的优点是大而全,缺点也就露出来,这么多的资源一次性全部加载,肯定会造成cpu资源的浪费 flask flask原生组件几乎为零,只有底层的jinja2(模板)和Werkzeug(服务器),属于短小精悍型框架, flask通常用于小型应用和快速构建应用,其强大的第三方库足以支持一个大型项目 Tornado 主要特点是原生异步非阻塞,在IO密集型和多任务处理上占据压倒性的优势,属于专注性框架,通 常用于API后端应用,游戏服务后台,其内部实现的异步非阻塞真的是很稳,优点是异步,缺点是干净,连个session也不支持 什么是flask的框架 web访问流程 web框架 flask简介 创建flask的虚拟环境 windos下用pycharm创建flask的虚拟环境 windows下,直接在user目录中创建一个pip目录,如:C:\Users\xx\pip,新建文件pip.ini 内容如下 [global] index-url = https://pypi.tuna.tsinghua.edu.cn/simple 利用pycharm的优点自动创建虚拟环境 写模板程序 from flask import Flask app = Flask(__name__) @app.route("/") def index(): return "hello word" if __name__ == "__main__": app.run(port=9001, debug=True) Flask参数的配置 import_name, #相当于 __name__/"__main__" static_path=None, #静态路径 static_url_path=None, #规定了哪种类型的url是静态请求 static_folder=‘static‘, #如果是静态请求,去static文件夹找文件 template_folder=‘templates‘, #静态模板,去templates中找模板文件 instance_path=None, #论坛 instance_relative_config=False #应用程序的配置 加载配置的方式 DEBUG = True 设置为调试模式 app.config.from_object() 从对象中加载 class Config(object): DEBUG = True app.config.from_object(Config) 从配置文件中加载 从config.ini文件中加载的内容为 DEBUG = True app.config.from_object("config.ini") 从环境变量中加载(不推荐使用) 常用配置的参数 app.debug = True app.config["DEBUG"] = True app.run()的三个参数 host="127.0.0.1" port=9001 debug = True JSON的数据格式 json中的数据一定要加双引号("") json中的数据实际就是一种在特定格式下显示的字符串 json中的数据一般是POST请求方式 json常用的方法 json.dump() json.dumps() #将字典对象转化为标准格式的json字符串,没有格式化(按照代码中定义的json格式) json.load() json.loads() #将json格式的字符串转化为Python对象(字典) jsonify() #将字典对象转化为标准格式的json字符串,格式化显示 如果JSON数据中有中文,在浏览器显示是unicode编码,需设置如下: #将默认的ASCII编码屏蔽掉,才能在浏览器中显示当前json数据中的具体内容 app.config["JSON_AS_ASCII"] = False json_data = { "name": "张三", "age": 20, "gender": "男" } 重定向(redirect) @app.route("/redirect") def func_redirect(): #跳转到百度等其他网页 #return redirect("http://www.baidu.com") #跳转到当前路径下的某个文件 return redirect(url_for("要跳转的函数名",是否携带参数)) 提供模板文件(render) 在当前路径中必许有一个文件夹叫templates,其中存放html中的模板代码,否则会有一个 jinja2.exceptions.TenplatesNotFound的错误 @app.route("/home") def home(): return render_template("/test.html") //直接跳转到test.html视图中 自定义状态码 如何自定义状态码 @app.route(‘/login‘) def func(): return ‘login‘,666 #实际上是一个元祖,犹如 return("login",666) 路由的参数配置 url中参数的定义 尖括号(<int:result>)中存放的是转换器和参数,参数的名称以及对参数类型的限制 请求类型的指定 默认是GET的请求模式 app.route("",methods=["GET","POST"]) #app.route()定义规则 用request.method获取当前请求,查看当前请求是那种请求方式 自定义转换器 自定义一个类继承BaseConverter 重写父类的regex变量 在app.url_map.converters这个字典中增加一组当前所定义的转换器数据(自己定义名字) 像使用int转换器一样的使用它 让自定义的转换器能够接收参数 自定义一个类继承BaseConverter 用super重写init方法,在init方法中需要有url_map这个参数以及正则表达式的参数*args,这个参数是我们在使用转换器的时候我们自己传递过来的 在app.url_map.converters这个字典中增加一组当前所定义的转换器数据 @app.route("/demo/<re(r‘a[0-9]{6}‘):uname>") BaseConverter中的其他两个参数的执行时机 转换器to_python 匹配和调用的先后顺序:一定是先匹配,再调用视图函数 to_python调用的时机:匹配了url之后,在调用视图函数之前 to_python的作用:用来决定视图函数中的参数的值 转换器to_url to_url是给url_for这个函数使用 作用:决定url_for 中我们传递的参数,最终的地址栏中所呈现出来的状态 请求错误的处理方式 主动抛出状态码(abort) 统一处理错误(@app.errorhandler(404/500/Exception)) @app.route("/") def index(): return "hello word" @app.route("/login") def func_login(): result = 4/0 abort(404) return "login......" @app.route("/register") def func_register(): result = 100 + "111" abort(500) return "regsit......" @app.errorhandler(ZeroDivisionError) def errorhandler(e): return "除数不能为0" @app.errorhandler(TypeError) def errorhandler(e): return "整型和字符型的数据不能进行运算" @app.errorhandler(404) def func_browser(e): return "浏览器正在更新,请稍等" @app.errorhandler(500) def func_server(e): return "服务器繁忙,请稍后" @app.errorhandler(Exception) def errorhandler(e): return "页面正在加载,请稍后" if __name__ == "__main__": app.run(port=9001, debug=True) 钩子函数(回调函数) before_first_request 时机: 在开启服务器之后的第一次请求 before_request 时机: 每一个请求之前 使用场景: 对请求统一进行处理,比如黑名单功能 绑定IP地址remote_addr=="192.168.15.60" after_request 时机: 每一次没有报错的请求之后 场景: 统一的对没有报错的响应进行响应头信息增加,如: response.headers["Content-Type"] = "application/json" teardown_request 时机: 每一次请求之后,都会调用 场景: 对错误进行收集 request请求知识 获取请求类型:request.method #获取当前是哪一种请求方式 获取请求的ip地址:request.remote_addr #访问IP地址 获取请求的数据: request.args.get("xxx") #GET请求数据 获取URL中的参数 request.form.get("xxx") #POST请求数据 获取form表单中的数据 request.files.get("xxx") #获取文件数据 list(request.form.keys("name","pwd")) request.values.get("user") #取不到返回None request.values["user"] #直接取用户名 request.values.to_dict() #获取当前表单提交中的所有数据 request.data() #request是基于mimetype进行处理的 request.headers() print(type(request.headers)) """ Host: 127.0.0.1:5000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:60.0) Gecko/20100101 Firefox/60.0 Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 Accept-Language: zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2 Accept-Encoding: gzip, deflate Referer: http://127.0.0.1:5000/home Content-Type: application/x-www-form-urlencoded Content-Length: 26 Cookie:csrftoken=vDIozqveCEfArdYXlM6goHVlSQEn7h4bDygNphL2Feas60DiM2di0jlqKfxo7xhA Connection: keep-alive Upgrade-Insecure-Requests: 1 Cache-Control: max-age=0 """ #获取当前的url路径 print(request.path) #/req # 当前url路径的上一级路径 print(request.script_root) # 当前url的全部路径 print(request.url) # http://127.0.0.1:5000/req # 当前url的路径的上一级全部路径 print(request.url_root ) # http://127.0.0.1:5000/ 注意事项 如果url和form中的Key重名的话,form中的同名的key中value会被url中的value覆盖 #http://127.0.0.1:5000/req?id=1&user=20 print(request.values.to_dict()) #{‘user‘: 20 ‘pwd‘: ‘DragonFire‘, ‘id‘: ‘1‘} 请求参数携带参数的几种方式 1、http://127.0.0.1/login/zhangan/123456 #直接在地址栏中输入 2、http://127.0.0.1/login?uname=zhangsan&upwd=123456 #利用GET请求 3、http://127.0.0.1/login #利用POST请求 uname=zhangsan&upwd=123456 状态的保持 http默认是无状态的,前一个请求和后一个请求之间是独立的,这个是http协议的特性 基于他的这种特性,如果想让不同请求之间可以有关联,需要引入cookie机制 设置cookie cookie是存储在浏览器端的键值字符串,会伴随着浏览器的自求自动提交到服务器,不同的网站不能共享cookie,保存在本地浏览器中安全性较低, 浏览器第一次发起登录请求该网站时,,如果服务器检测到账号和密码正确,就会给该请求设立一个cookie,浏览器会自动把cookie保存起来, 下一次请求登录时会把该cookie带到服务器,服务器从当前请求中获取当前所使用的cookie,根据cookie就可以判断当前是谁登录 from flask import Flask, make_response, request app = Flask(__name__) # 存储在客户端 @app.route("/") def index(): user = request.cookies.get("user_name") id = request.cookies.get("user_id") return "%s---%s"%(user,id) @app.route("/login") def login(): response = make_response("success") response.set_cookie("user_name", "zhangsan",max_age=3600) response.set_cookie("user_id", "2",max_age=3600) # return "success" return response @app.route("/logout") def logout(): response = make_response("success") response.delete_cookie("user_name") response.delete_cookie("user_id") return response if __name__ == "__main__": app.run(port=9001, debug=True) 设置session 存储在服务器上,对于敏感、重要的信息,建议要存储在服务器端,不能存储在浏览器中,如用户名、余额、等级、验证码等信息在服务器端进行状态保持的方案就是session session依赖于cookie from flask import Flask, session app = Flask(__name__) app.config["SECRET_KEY"] = "wxb" # 存储在服务器上 @app.route("/") def index(): user_id = session.get("user_id", "") user_name = session.get("user_name", "") return "%s---%s"%(user_id,user_name) @app.route("/login") def login(): session["user_name"] = "lisi" session["user_id"] = "1" return "success" @app.route("/logout") def logout(): session.pop("user_name",None) session.pop("user_id",None) return "success" if __name__ == "__main__": app.run(port=9001, debug=True) 上下文管理器(类似全局变量) 请求上下文 request 当请求发生时,调用视图函数,触发request.get() session 抛出异常 RuntimeError:working outside of request context 应用上下文 current_app current_app.config.get("DEBUG") g变量 一般作用于跨py文件,先用g.num存取变量,在再另一个py文件中取值 抛出异常 RuntimeError:working outside of application context flask_script pip install flask_script from flask import Flask flask_script import Manager app = Flask(__name__) manager = Manager(app) @app.route("/") def index(): return "hello world" if __name__ == "__main__": manager.run(debug=True) flask中可以return的几种写法 1)return "字符串" 2)return "字符串",666 3)return redirect("/") 4)response = make_response("字符串") response.set_cookie(‘username‘, username) return response 5)return render_template("demo.html",mylist=["haha","hehe"]) 6)response = make_response(render_template("index.html")) response.set_cookie(‘username‘, username) return response 7)response = redirect(url_for(‘transfer‘)) response.set_cookie(‘username‘, username) return response
jinja2模板规范 在当前项目中创建一个文件为templates的文件夹,将其设置为模板文件夹,新建的html为模板页面, 在视图函数中使用render_template(".html的文件", my_list=mylist),my_list作为在模板页面使用的的变量 {{ my_list}} 过滤器 符号 "|" 管道左边作为输入传一个变量到管道右边进行输出 safe 对字符串的html标签的代码进行解析,并以html显示在当前文件 reverse 翻转 upper 大写 lower 小写等 自定义过滤器(本身相当于一个函数) @app.template_filter("valreverse") #将其添加到过滤器组中 def add_after(value): value += "Hello world" result = "¥" + value + "&&" return result 模板中的for和if loop.index # 获取下标为0的数据 loop。index0 # 获取下标为1的数据 {% for ret in result %} # 获取下标索引为0的数据 {% if loop.index == 1 %} <li style="background-color: red">{{ ret.data }}</li> alert({{ ret.data }}) {% elif loop.index == 2 %} <li style="background-color: green">{{ ret.data }}</li> {% elif loop.index == 3 %} <li style="background-color: fuchsia">{{ ret.data }}</li> {% else %} <li style="background-color: cyan">{{ ret.data }}</li> {% endif %} {% endfor %} 模板代码的复用 宏 {% macro func_macro() %} // 这里填想要封装的html代码 {%endmacro %} {% import html模板 %} 导入到其他模块中使用 该模板中含有func_macro函数 继承 导入模板文件 // 继承基类中的html代码 {% "extends base_index_detail.html" %} // 以下代码是进行挖坑和填坑的操作 {% block titleBloock %} // 自己独有的代码块 {% endblock %} 包含 include() ignore missing // 忽略错误的 模板中特有的变量和函数 在py文件中和模板文件中都可以直接拿来使用,不需要传参 request session g config url_for() get_flashed_messages() 与 flash搭配使用 代码如下: @app.route("/login") def login(): g.name = "xiaoming" session["username"] = "zhangsan" flash("哈哈哈") flash("嘻嘻嘻") flash("呵呵呵") return render_template("demo_unique.html") html模板中的内容为: config: {{ config.DEBUG }} <br> session: {{ session["username"] }}<br> request: {{ request.url }}<br> g变量: {{ g.name }} <br> 两个函数为: <a href="{{ url_for(‘index‘) }}">回到首页</a><br/> flash结果为: {% for data in get_flashed_messages() %} {{ data }} {% endfor %} flask_wtf表单 pip install flask_wtf 原生的form表单和用类生成的对象,再用对象去创建这个表单 Web 表单是 Web 应用程序的基本功能 它是HTML页面中负责数据采集的部件,表单有三个部分组成:表单标签、表单域、表单按钮, 表单允许用户输入数据,负责HTML页面数据采集,通过表单将用户输入的数据提交给服务器 CSRF 跨站请求伪造 flask_wtf中有个generate_csrf 会自动生成CSRF CSRF全拼为Cross Site Request Forgery,译为跨站请求伪造 CSRF攻击 CSRF指攻击者盗用了你的身份,以你的名义发送恶意请求 包括:以你名义发送邮件,发消息,盗取你的账号,甚至于购买商品,虚拟货币转账...... 造成的问题:个人隐私泄露以及财产安全 开启CSRF验证 app.config[‘WTF_CSRF_ENABLED‘] = True 防止CSRF攻击 在客户端向后端请求界面数据的时候,后端会往响应中的 cookie 中设置 csrf_token 的值在 Form 表单中添加一个隐藏的的字段,值也是 csrf_token, 在form表单中设置csrf <input type="hidden" name="csrf_token" value="{{ csrf_token() }}"> 在用户点击提交的时候,会带上这两个值向后台发起请求 后端接受到请求,以会以下几件事件: 从 cookie中取出 csrf_token从表单数据中取出来隐藏的 csrf_token 的值进行对比如果比较之后两值一样,那么代表是正常的请求, 如果没取到或者比较不一样,代表不是正常的请求,不执行下一步操作
标签:协议 推荐 load host nic 支持 method lte 规则
原文地址:https://www.cnblogs.com/inhocho/p/13503954.html