目录
请求对象
响应对象
session的使用和原理
闪现(flash)
请求扩展
蓝图
请求对象
请求对象request是全局的,需要导入这个全局的request,在哪个视图函数中就是当次的request对象
请求数据:
request.method # 获取提交的方法
request.args # 获取get请求提交的暑假
request.form # 获取post请求提交的数据
request.values # post和get提交的数据总和
request.cookies # 客户端所带的cookie
request.headers # 获取请求头
request.path # 不带域名,请求路径
request.full_path # 不带域名,带参数的请求路径
request.url # 带域名带参数的请求路径
request.host_url # 请求URL方案和主机
request.files # 文件上传数据
request.data # 二进制的请求数据 上传json格式
响应对象
response对象四件套
render_template # 返回模板
redirect # 重定向
jsonify # 返回json格式数据
'' # 返回字符串类型
响应头中加参数:
有时候视图不返回响应对象时但可以返回Flask本身转换为响应对象的值,因此为其添加首部变得棘手。可以调用这个函数而不是使用return,你将得到一个响应对象,你可以使用它来附加header
flask.make_response(*args)
from flask import Flask, make_response, render_template
app = Flask(__name__)
@app.route('/')
def index():
res = 'helloe'
res = make_response(res)
res.headers['name'] = 'abc'
return res
将cookie写入
@app.route('/')
def index():
res = make_response('ok')
res.set_cookie('name', 'abc')
# res.delete_cookie('name')
return res
'''
set_cookie()参数
key # 要设置的cookie的键(名称)。
value # cookie的值。
max_age # 应该以秒为单位,或者None(默认值),如果cookie只在客户端浏览器会话期间存在。
expires # 应该是一个datetime对象或UNIX时间戳。
path # 将cookie限制在给定路径下,默认情况下它将跨越整个域。
domain # 如果要设置跨域cookie。例如,domain=".example.com"将设置一个cookie,该cookie可由域名www.example.com、foo.example.com等读取。否则,cookie只能由设置它的域读取。
secure # 如果为True, cookie只能通过HTTPS访问。
httponly # 禁止JavaScript访问cookie。
samesite # 将cookie的作用域限制为仅附加给“same-site”请求。
'''
前后端分离和混合的cookie
前后端混合,cookie是后端写入的
- res.set_cookie("","") 混合通过这样写浏览器就能把cookie保存到cookie中
- 本质是后端把cookie放到响应头中,浏览器读到响应头中有cookie把cookie写入到浏览器中
前后端分裂
- 直接把客户端要存到cookie中的数据,放到响应体中
- 前端(浏览器,app,小程序),自己取出来放到相应的位置
浏览器使用js自己写入到cookie,app自己使用代码写入到某个位置
session的使用和原理
在django中session的使用,举例在视图类中:
from django.http import HttpResponse
def login(request):
request.session['name'] = 'abc'
return HttpResponse('ok')
def permissions(request):
if request.session.get('name'):
return HttpResponse('允许')
return HttpResponse('不允许')
使用和原理图:
在flask中session的使用
from flask import Flask, session
app = Flask(__name__)
app.debug = True
app.secret_key = 'asdfghjk'
@app.route('/login')
def login():
# 设置值
session['name'] = 'abc'
return 'ok'
@app.route('/show')
def permissions():
# 获取值
session.get('name')
return 'ok'
if __name__ == '__main__':
app.run()
flask的session执行流程源码分析:
请求来了会先执行app()
def wsgi_app(self, environ, start_response):
ctx = self.request_context(environ)
try:
try:
ctx.push() # 它的源码
response = self.full_dispatch_request()
except Exception as e:
error = e
response = self.handle_exception(e)
except:
error = sys.exc_info()[1]
raise
return response(environ, start_response)
finally:
ctx.pop(error)
执行ctx.push()
# ctx.push 的 373行左右
if self.session is None:
session_interface = self.app.session_interface
self.session = session_interface.open_session(self.app, self.request)
if self.session is None:
self.session = session_interface.make_null_session(self.app)
请求来了执行 session_interface.open_session
def open_session(
self, app: "Flask", request: "Request"
) -> t.Optional[SecureCookieSession]:
s = self.get_signing_serializer(app)
if s is None:
return None
# val 就是从cookie中取出的三段,反序列化解密保存到session中
val = request.cookies.get(self.get_cookie_name(app))
if not val:
return self.session_class()
max_age = int(app.permanent_session_lifetime.total_seconds())
try:
data = s.loads(val, max_age=max_age)
return self.session_class(data)
except BadSignature:
return self.session_class()
请求走了执行 save_session
def save_session(self, app, session, response):
name = self.get_cookie_name(app)
domain = self.get_cookie_domain(app)
path = self.get_cookie_path(app)
secure = self.get_cookie_secure(app)
samesite = self.get_cookie_samesite(app)
httponly = self.get_cookie_httponly(app)
if not session: # 如果视图函数放了,不为空 session['name']='abc'
if session.modified: #
response.delete_cookie(
name,
domain=domain,
path=path,
secure=secure,
samesite=samesite,
httponly=httponly,
)
return
if session.accessed:
response.vary.add("Cookie")
if not self.should_set_cookie(app, session):
return
expires = self.get_expiration_time(app, session)
# 序列化---》加密了
val = self.get_signing_serializer(app).dumps(dict(session)) # type: ignore
# 三段:
response.set_cookie(
name, # session
val, # 三段:
expires=expires,
httponly=httponly,
domain=domain,
path=path,
secure=secure,
samesite=samesite,
)
总结:session执行流程
1.请求来的时候会执行open_session,取出cookie判断是否为空,如果不为空把它反序列化、解密转成字典,然后放到session对象中
2.请求走的时候会执行save_session,把session转成字典序列化加密成三段放到cookie中
闪现(flash)
作用:当访问a页面的时候出了错重定向到b页面,要在b页面渲染a页面的错误信息;在某个请求中放入值,另一个请求中取出,取出后就没了
from flask import flash, Flask, get_flashed_messages
app = Flask(__name__)
app.secret_key = 'asdfghjkl'
@app.route('/index')
def index():
flash(message='闪现')
# 还可以指定分类
# flash(message='橘子', category='1')
# flash(message='苹果', category='1')
# flash(message='猪肉', category='2')
# flash(message='羊肉', category='2')
return 'index'
@app.route('/home')
def home():
# 取出列表
res = get_flashed_messages()
print(res) # ['闪现']
# res = get_flashed_messages(category_filter=('1',))
# ['橘子', '苹果']
return 'home'
if __name__ == '__main__':
app.run()
请求扩展
在请求进入视图函数之前执行的一些代码与请求出了视图函数之后执行的一些代码,类似于django的中间件完成的功能
1 before_request:在请求进视图函数之前执行
- 有多个,从上往下依次执行。
- 如果返回了response对象,就直接返回。
2 after_request:在请求从视图函数走之后执行
- 有多个,从下往上依次执行。
- 要参数和返回值
3 before_first_request:项目启动后,第一次访问会执行,以后再也不执行了
- 项目启动后初始化
4 teardown_request:每一个请求之后绑定一个函数,即使遇到了异常,每个请求走,都会执行,记录错误日志
5 errorhandler路径不存在时404,服务器内部错误500
6 template_global 标签 ,在模板中用 {{ 标签() }}
7 template_filter过滤器 在模板中用 {{参数1 | 过滤器(参数2, 参数3)}}
蓝图
blueprint:对目录进行划分,因为之前的flask代码都是一个一个的py文件后期我们肯定需要划分一下文件,蓝图就是用来划分目录的(划分目录没有固定的模版,只要结构划分清楚就可以)
小型项目:
flask_blueprint_little # 项目名
- src # 项目源代码
- __init__ # app对象创建的地方
- templates # 模板
- home.html
- static # 静态文件
- views # 视图函数存放位置
- user.py # 用户相关视图
- login.py # 登陆相关视图
- settings.py # 配置文件
- manage.py # 启动文件
大型项目:
flask_blurprint_big # 项目名字
-src # 项目代码所在位置
-__init__.py # src的init,falsk,app实例化
-settings.py # 配置文件
-admin # 类似于django的admin app
-__init__.py # 蓝图初始化
-template # 模板
-backend.html
-static # 静态文件
-xx.jpg
-views.py # 视图层
-models.py # models层,后期咱们表模型
-api
-__init__.py
-template
-static
-models.py
-views.py
-manage.py # 启动文件