请求钩子&状态保持[session与cookie]&上下文
请求钩子
前言
什么是请求钩子?在客户端和服务器交互的过程中,有些准备工作或扫尾工作需要统一处理,为了让每个视图函数避免编写重复功能的代码,flask提供了统一的接口可以添加这些处理函数,即请求钩子。
请求钩子的原理
先回顾一下flask对请求的处理流程:
接收请求–>创建请求上下文–>请求上下文入栈–.>创建该请求的应用上下文–.>应用上下文入栈–>处理逻辑–>请求上下文出栈–>应用上下文出栈
看了这个过程,flask放置请求钩子的位置有:处理逻辑之前,处理逻辑之后,应用上下文出栈之前。
flask有五种常用请求钩子:
before_first_request:在处理app第一个请求前运行。
before_request:在每次请求前运行。
after_request:如果处理逻辑没有异常抛出,在每次请求后运行。
teardown_request:在每次请求后运行,即使处理发生了错误。
teardown_appcontext:在应用上下文从栈中弹出之前运行
from flask import Flask
from flask import abort
app = Flask(__name__)
# 第一个请求钩子
# 在第一次请求之前调用,可以在此方法内部做一些初始化操作
# 功能:
# 1.在处理第一次请求前执行
# 2.利用:进行数据库的连接操作
@app.before_first_request
def before_first_request():
print("before_first_request")
# 第二个请求钩子
# 在每一次请求之前调用,这时候已经有请求了,可能在这个方法里面做请求的校验
# 如果请求的校验不成功,可以直接在此方法中进行响应,直接return之后那么就不会执行视图函数
# 功能:
# 1.在每一次请求调用之前运行
# 2.调用的时候不需要传参
# 3.如果他有一个非空的返回值,name返回值会被当做响应,之后请求讲不会进入视图进行处理
# 4.运用
# 1.数据库连接
# 2.在session中下载用户的相关信息
@app.before_request
def before_request():
print("before_request")
# if 请求不符合条件:
# return "laowang"
#第三个请求钩子
# 在执行完视图函数之后会调用,并且会把视图函数所生成的响应传入,可以在此方法中对响应做最后一步统一的处理
# 注意点:
# 1.在每一次请求之后运行
# 2.调用的时候需要传递参数,参数是一个响应对象
# 3.必须有返回值,返回值也是一个响应对像,可处理可不处理
# 4.不能在debug模式下运行
@app.after_request
def after_request(response):
print("after_request")
response.headers["Content-Type"] = "application/json"
return response
#第四个请求钩子
# 请每一次请求之后都会调用,会接受一个参数,参数是服务器出现的错误信息
# 注意点:
# 1.在每次请求最后运行
# 2.会接受一个参数,参数是服务器出现的错误信息
@app.teardown_request
def teardown_request(e):
print("teardown_request")
@app.route('/')
def index():
return 'index'
if __name__ == '__main__':
app.run(debug=True)
// 第一次
before_first_request
before_request
after_request
teardown_request
// 第二次请求
before_request
after_request
teardown_request
状态保持
cookie
from flask import Flask,request
from flask import make_response
app = Flask(__name__)
@app.route('/getcookie') #得到cookie
def getcookie():
print('===========')
print(request.cookies)
return '取出cookie'
@app.route('/index',methods=['GET','POST'] ) #设置cookie
def index():
response = make_response('ok') #生成响应数据
response.set_cookie('username','tom')#设置cookie
return response
if __name__ == '__main__':
app.run(debug=True)
注意点:session是依赖于cookie而存在,因为cookie存有session的id
session
from flask import Flask,session
import os
app = Flask(__name__)
#生成秘钥
app.secret_key = os.urandom(24)
#秘钥类似:b'e[Y\x10O"\xa0\xc4\x7fFv\x9c\xd4\xd7\xa31\n\x0bqz\x15]\xb6\xba'
@app.route('/getinfo')
def getinfo():
return session.get('username')#获取session的值
@app.route('/index',methods=['GET','POST'])
def index():
session['username'] = 'zhangsan'# 设置session的值
return 'ok'
if __name__ == '__main__':
app.run(debug=True)
注意点:
1.session依赖于cookie的,因为cookie存有session的id
2.Session在使用过程中,必须指定secret_key(密钥)
上下文
概念
上下文:相当于容器,保存了一些程序运行的时候需要的信息
请求上下文(request context)
请求上下文:保存的是客户端与服务端交互的数据
请求上下文对象:
request:封装是HTTP请求的内容
session:记入了当前会话的信息,就是用来保存用户信息
应用上下文
应用上下文:程序运行的时候,保存的数据信息
应用上下文对象:
current_app
存储变量:
1.加载的配置文件
2.连接了哪些数据库
3.运行在哪个机器上,IP多少
4.等
g变量
Flask 程序全局的一个临时变量,充当中间人的作用
例:
g.name = ‘张三’
请求上下文
print(request) #效果:<Request 'http://127.0.0.1:5000/index' [GET]>
print(session) #效果:<NullSession {}>
应用上下文
print(current_app) #效果:<Flask 'day'>