http是一个无状态协议,也就是说上一次的请求和这一次的请求没有关系,cookie和session的出现解决了这个问题。
- cookie:第一次的登陆的时候,客户端会发送请求给服务器,服务器会返回数据给浏览器,也就是cookie,然后浏览器保存在本地,当该用户再次发送请求时,会自动把存储在本地的cookie数据携带给服务器,服务器通过cookie判断当前是哪个用户。cookie存储的数量有限,一般不超过4KB。
- session:session和cookie类似,只不过cookie存储的是用户的信息,session存储的往往只是一个id ,一个辨别用户身份的钥匙。用户的大部分数据都是存储在服务器端。session的出现是为了解决cookie存储数据的不安全。
- cookie和session的结合:两种方式:第一种:存放在服务器,标识信息的session_id往往存放在cookie中用来辨识用户,服务器接受到cookie后,解析出session_id ,然后再去服务器中查找。第二种:将session数据加密然后存放在cookie中,这种专业术语叫做client side session,flask采⽤的就是这种⽅式,当然也可以替换成别的方式。
Cookie
在flask中可以设置cookie,需要通过Response对象来操作
如果不设置过期时间,那么关了浏览器cookie就会过期。
from flask import Flask, Response
from datetime import datetime
app = Flask(__name__)
@app.route('/')
def index():
res = Response('主页')
expires = datetime(2020,9,7,0,0,0)
res.set_cookie('name','xiaoz',expires=expires)
res.set_cookie('age','19',max_age=20)
return res
可以去页面查看一下:
session
Flask中的session是把session数据加密然后存放在cookie中,需要导入session,加密需要设置配置项'SECRET_KEY'
为随机字符
- permanent:持久化
- pop:移除单个值
- clear:清空所有的值
from flask import Flask, session
import os
from datetime import timedelta
app = Flask(__name__)
# 密钥
app.config['SECRET_KEY'] = os.urandom(44)
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=10)
@app.route('/')
def index():
name = session.get('name')
age = session.get('age')
print(age)
print(name)
return "首页"
@app.route('/login/')
def login():
session['name'] = 'xiaoz'
session['age'] = 19
# 设置持久化 默认为1个月,也可以设置['PERMANENT_SESSION_LIFETIME']
session.permanent = True
return "登陆成功"
@app.route('/logout/')
def logout():
# pop删除单个值
# session.pop('age')
session.clear() #清空session
return "退出登陆"
Flask上下文
Flask提供了两种上下文,一种是应用上下文(Application Context),一种是请求上下文(Request Context)。应用上下文就是调用app = Flask(__name__)
创建的这个对象app,请求上下文就是每次发送http请求时,在flask内创建的request对象。
- current_app:应用上下文对象,
访问当前app的配置项
@app.route('/')
def index():
print(current_app.config['DEBUG'])
print(current_app.config['SECRET_KEY'])
return "首页"
- g :应用上下文对象,处理请求时用作临时存储的对象
因为是全局变量,所以设置了g的属性之后,在别的文件导入g就可以使用g的属性了
from flask import Flask, session, g
from utils import log_a, log_b
@app.route('/')
def index():
name = session.get('name')
g.name = name
log_a()
log_b()
return "首页"
-------------------------------------------------
# utils.py
from flask import g
def log_a():
print('log a %s'%g.name)
def log_b():
print('log b %s'%g.name)
- request:请求上下文的对象,这个对象一般用来保存一些请求的变量。比如method、args、form等。
- session:请求上下文上的对象。这个对象一般用来保存一些会话信息。
钩子hook
- before_first_request:处理第⼀次请求之前执⾏
@app.before_first_request
def handel_first_request():
print("这是在第一个request之前执行")
- before_request:在每次请求之前执⾏
@app.before_request
def handel_before():
print("这是每个请求之前")
- after_request:每次请求之后执行,需要传递response参数并返回
@app.after_request
def handel_after(response):
print("每个请求之后执行")
return response
- teardown_appcontext:不管是否有异常,都在最末尾执行
@app.teardown_appcontext
def handel_teardown(response):
print("最后执行")
return response
- context_processor:上下文处理器。返回的字典中的键可以在模板上下文中使用。在这里返回之后,render_template后就不需要传参给模板了。
# 上下文处理器
@app.context_processor
def context():
return {'name':'lgcoder'}
- errorhandler:接收状态码,并自定义返回页面的方法。
# 接收状态码 ,可以自定义状态码的处理方法
@app.errorhandler(404)
def page_not_find(error):
return "页面不存在",404
- abort(404):主动抛出404错误,可以被 errorhandler 接收