会话:服务器端和客户端之间的交互
一个服务器可以被多个浏览器访问,他们之间是通过http协议来完成访问的(1、先请求,后响应;2、响应后会断开连接;3、一次请求就结束了),cookie的作用就是让服务器能够认识浏览器,常用于登录。
cookie 本身由浏览器保存,通过response将cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带cookie过来。
cookie 工作原理(以登录为例说明):1.浏览器登录,2.服务器验证用户名和密码(通过之后返回cookie给浏览器),3.浏览器自动保存cookie到本地,4.下一次浏览器请求登录该服务器会在请求的同时自动携带浏览器的cookie,5.服务器会取出cookie值,判断是哪个用户在访问,返回对应的用户数据给浏览器,如下图 1 所示。
cookie :是通过服务器创建Response来创建的,它的作用就是能够让服务器在一段时间内记住访问过服务器的客户端。
cookie操作:
练习:以登录过程为例子(如上图 1 ),用Flask实现用户登录,用户注销的功能模拟
1、项目框架(从上一个文章项目中复制的框架参考连接)
2、home.html代码:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>首页title>
head>
<body>
<h2>首页h2>
<hr>
{# 不要进行前端的页面跳转,要带着数据跳转要经过后端#}
{# 下面用到的是jinja2模板语言,需要在setting中设置#}
{% if username %}
<p>
当前登录用户:{{ username }}
<a href="/logout/">注销a>
p>
{% else %}
<a href="/login/">登录a>
{% endif %}
body>
html>
3、login.html代码:
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录title>
head>
<body>
<h2>登录h2>
<hr>
{# <form action=""method="post">#}
{# <form action="{{ url_for('user.login') }}" method="post">form> #}
<form action="/login/" method="post">
<p>
用户名:<input type="text" name="username">
p>
<p>
密码:<input type="password" name="password">
p>
<p>
<button>提交button>
p>
form>
body>
html>
4、__init__代码:
# __init__.py : 初始化文件,创建Flask应用
from flask import Flask
from .views import blue
def creat_app():
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(blueprint=blue)
return app
5、models代码:
# models.py : 模型,数据库
6、views代码
# 在views.py中放路由和视图函数
import datetime
from flask import Blueprint, render_template, request, redirect
from .models import * #后面是用views来控制数据库的,所以要在views中导入models文件
# 蓝图
blue = Blueprint('user', __name__)
# 首页(一个页面可以由多个路由,也就是说可以有多个装饰器)
@blue.route('/')
@blue.route('/home/')
def home():
# 4. 获取cookie
username = request.cookies.get('user')
return render_template('home.html', username=username)
@blue.route('/login/',methods = ['GET','POST'])
def login():
# GET:访问登陆页面
if request.method == 'GET':
return render_template('login.html')
elif request.method == 'POST':
pass
# 1. 获取前端提交过来的数据
username = request.form.get('username') # 写在括号里的username要和前端一致
password = request.form.get('password') # 写在括号里的password要和前端一致
# 2. 模拟登录:用户名和密码验证
if username == 'zhangsan' and password == '321':
# 登陆成功
response = redirect('/home/')
# 3. 设置cookie
# cookie不能用中文
# response.set_cookie('user',username) # 默认浏览器关闭则cookie失效
# 过期时间:max_age: 秒
# response.set_cookie('user',username,max_age=3600 * 24 * 4)
response.set_cookie('user',username,expires=datetime.datetime(2023,5,10))
return response
# 注销
@blue.route('/logout/')
def logout():
response = redirect('/home/')
# 5. 删除cookie
response.delete_cookie('user')
return response
7、app代码
from App import creat_app
app = creat_app()
if __name__ == '__main__':
app.run(debug=True)
总结:上面的框架只是对cookie最直接的演示和说明
# __init__.py : 初始化文件,创建Flask应用
from flask import Flask
from .views import blue
import datetime
def creat_app():
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(blueprint=blue)
# session配置
print(app.config) # Flask的配置信息
'''
'''
# 这里SECRET_KEY可以自己设置,它的作用就就是对照解析session中对应的value加密值
app.config['SECRET_KEY'] = 'abcdef123'
# 设置session的存在时间
app.config['PERMANENT_SESSION_LIFETIME'] = datetime.timedelta(days=20)
return app
2、改动的views代码
# 在views.py中放路由和视图函数
import datetime
from flask import Blueprint, render_template, request, redirect, session
from .models import * #后面是用views来控制数据库的,所以要在views中导入models文件
# 蓝图
blue = Blueprint('user', __name__)
# 首页(一个页面可以由多个路由,也就是说可以有多个装饰器)
@blue.route('/')
@blue.route('/home/')
def home():
# 4. 获取session
username = session.get('user')
return render_template('home.html', username=username)
@blue.route('/login/',methods = ['GET','POST'])
def login():
# GET:访问登陆页面
if request.method == 'GET':
return render_template('login.html')
elif request.method == 'POST':
pass
# 1. 获取前端提交过来的数据
username = request.form.get('username') # 写在括号里的username要和前端一致
password = request.form.get('password') # 写在括号里的password要和前端一致
# 2. 模拟登录:用户名和密码验证
if username == 'zhangsan' and password == '321':
# 登陆成功
response = redirect('/home/')
# 3. 设置session
session['user'] = username
session.permanent = True # 有这条语句,session的存在时间才能显示出来(expires)
return response
# 注销
@blue.route('/logout/')
def logout():
response = redirect('/home/')
# 5. 删除session
session.pop('user')
# session.clear() # 慎用,会删除服务器下所有session
return response
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>父模板title>
{# 通用css文件 #}
<link rel="stylesheet" href="{{ url_for('static', filename='css/base.css') }}">
{% block extcss %}
{% endblock %}
head>
<body>
{% block head %}
{% endblock %}
<hr>
{% block content %}
{% endblock %}
<hr>
{% block foot %}
{% endblock %}
<hr>
{# 通用的js文件 #}
<script src="{{ url_for('static', filename='js/base.js') }}">script>
{% block extjs %}
{% endblock %}
body>
html>
4、child1.html
{% extends 'base.html' %}
{# 继承base #}
{% block head %}
<p>child1YYDSp>
{% endblock %}
5、child2.html
{# 继承child1#}
{% extends 'child1.html' %}
{# super() #}
{% block head %}
{# 如果想要保留child1中的内容,就要调用super函数 #}
{{ super() }}
<p>child2YYDSp>
{% endblock %}
{# include:嵌入 #}
{% block content %}
<p>child2 contentp>
{% include 'child2_include.html' %}
{% endblock %}
{# 宏定义:相当于python函数 #}
{% macro person(name, age) %}
<b>姓名:{{ name }};年龄:{{ age }}b>
{% endmacro %}
{% block foot %}
{{ person('鸡', 23) }}
{# 过滤器 #}
<p>{{ name | capitalize }}p>
{% endblock %}
6、child2_include.html
<div>这是child2中通过include嵌套的内容,它写在child2_include.html中div>
7、home.html
DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>hometitle>
head>
<body>
<h2>Homeh2>
<hr>
{# 模板语言的注释:ctrl + / #}
<h4>变量:h4>
<p>name:{{ name }}p>
<p>num:{{ num }}p>
<p>hobby:{{ hobby }}p>
<hr>
<h4>标签:h4>
<h5>if语句h5>
{% if num <= 3 %}
<p>{{ name }} 排名前三p>
{% elif (num > 3) and (num <= 5) %}
<p>{{ name }} 排名靠前p>
{% else %}
<p>{{ name }} 排名靠后p>
{% endif %}
<hr>
<h5>for循环h5>
{% for ho in hobby %}
{% if loop.first %}
<p style="color: red;">{{ ho }}p>
{% else %}
<p style="color: blue;">{{ ho }}p>
{% endif %}
index:{{ loop.index }}
index0:{{ loop.index0 }}
reindex0:{{ loop.revindex0 }}
reindex:{{ loop.revindex }}
{% else %}
{# for循环的else只有在for循环无法执行时才会执行 #}
<p>for循环的elsep>
{% endfor %}
body>
html>
8、 __ init__
# __init__.py : 初始化文件,创建Flask应用
from flask import Flask
from .views import blue
def creat_app():
app = Flask(__name__)
# 注册蓝图
app.register_blueprint(blueprint=blue)
return app
9、views
# 在views.py中放路由和视图函数
from flask import Blueprint, render_template
from .models import * #后面是用views来控制数据库的,所以要在views中导入models文件
# 蓝图
blue = Blueprint('user', __name__)
@blue.route('/')
def home():
pass
data = {
'name': 'dingding',
'hobby': ['eating', 'sleep', 'dance'],
'num': 15
}
# return render_template('home.html', **data)
# return render_template('base.html')
# return render_template('child1.html')
return render_template('child2.html',**data)
10、 app
from App import creat_app
app = creat_app()
if __name__ == '__main__':
app.run(debug=True)