会话技术
出现场景
- 服务器如何识别客户端(服务器怎么知道你是你)
- Http在Web开发中基本都是短连接
请求生命周期
- 从Request开始
- 到Response结束
种类:cookie,session,token
Cookie
cookie本身由浏览器生成,通过Response将cookie写到浏览器上,下一次访问,浏览器会根据不同的规则携带cookie过来
cookie语法
response.set_cookie(key,value[,max_age=None,exprise=None)]
request.GET.get(key,defaultvalue)
response.set_cookie(key,value,max_age=None,exprise=None)生成cookie
response.set_signed_cookie(key,value,salt)生成加密cookie
max_age: 整数,指定cookie过期时间
expries
: 整数,指定过期时间,还支持是一个datetime或 timedelta,可以指定一个具体日期时间
max_age和expries两个选一个指定
过期时间的几个关键时间
max_age 设置为
0 浏览器关闭失效
设置为None永不过期
expires=timedelta(days=10) 10天后过期
- 客户端会话技术
- 数据存储在客户端
- cookie以键值对存储
cookie特性:
- 支持过期时间
- 默认Cookie会自动携带,本网站所有Cookie
- Cookie不能跨域名,跨网站
服务器怎么操作浏览器
- 通过HttpResponse
- **Cookie默认不支持中文,需要转换**
- 可以加盐
- 加密
- 获取的时候需要解密
实践:cookie
url:url('^setcookie/', views.set_cookie, name='set_cookie'),
views:
def set_cookie(request):
response = HttpResponse('设置cookie')
response.set_cookie('username', 'Rock') # 设置了cookie
return response
结果可以看到:
可以看到响应回cookie
这时我们再访问之前建立的hello
我们可以看到我们在请求时,是访问cookie请求的
接着我们再新建url用来获取cookie,并返回给客户端
url('^getcookie/', views.get_cookie, name='set_cookie'),
views
def get_cookie(request):
username = request.COOKIES.get('username')
return HttpResponse(username)
我们可以看到服务器成功获取并返回了我们的cookie
那这些可以有何用呢?我们可以用登录来做一个实验,详细请看下面的实践:cookie登录
实践:cookie登录实验
登陆
首先有一个页面(静态显示)
- 页面中有输入框
- 有登陆按钮
- 点完登陆,默认进入个人中心(静态显示)
- 个人中心可以显示用户名(逻辑操作)
我们新建一个url:
url('^login/', views.login, name='login'),
新建一个login.html模板
<title>login</title>
</head>
<body>
<form action="" method="post">
<span>用户名:</span><input type="text" placeholder="请输入用户名" name="uname">
<br>
<button>登录</button>
</form>
</body>
</html>
客户端向服务端传数据,数据有很多,以字典形式接收
5行中的name='uname'是指定k的字段
views:
def login(request):
return render(request, 'login.html', )
但是我们应该还有一个执行登录的接口,点击登录按钮,将用户名进行保存的操作(目前只存到前端)
新建url
url('^do_login/', views.do_login, name='do_login'),
views:
def dologin(request):
uname = request.POST.get('uname')
# 暂时不用登录验证,直接返回登陆成功
response = HttpResponse('登陆成功')
# 接着存到cookie
response.set_cookie('uname',uname)
return response
接着我们要设计一个个人中心
新建url:
url('^mine/', views.mine, name='mine'),
views:
def mine(request):
# 获取cookie
uname = request.COOKIES.get('uname')
return HttpResponse(uname)
然后补全html中的action路径
action="{% url 'app:do_login' %}
再将settings.py中的csrf注释掉
下面让我们进行测试:
首先查看mine页面
返回的是none这表名没有cookie返回给我们
我们再登录login:
然后点击登录,返回登录成功,再访问mine
我们可以看到成功返回
大概思路:输入用户名,用户名通过name='uname',通过前端进行存储,存储之后再将uname通过 uname = request.COOKIES.get('uname')
进行后端的获取,再将用户名返回给mine中。
优化:
- 修改views:
def do_login(request):
uname = request.POST.get('uname')
# 点击登录之后直接利用重定向跳转到mine页面,省去了手动输入mine页面地址操作
response = HttpResponseRedirect(reverse('app:mine'))
# 接着存到cookie
response.set_cookie('uname', uname)
return response
- 当我们没有点击过登录,直接访问mine返回的是none,这是我们需要自动跳转登陆界面:
def mine(request):
# 获取cookie
uname = request.COOKIES.get('uname')
if uname:
return HttpResponse(uname)
# redirect是重定向简写,reverse是views中的反向解析
return redirect(reverse('app:login'))
cookie一般默认浏览器关闭就消失
我们也可以设置cookie的过期时间
response.set_cookie('uname', uname, max_age=30)# 30秒
对cookie加盐
def do_login(request):
uname = request.POST.get('uname')
# 点击登录之后直接利用重定向跳转到mine页面,省去了手动输入mine页面地址操作
response = HttpResponseRedirect(reverse('app:mine'))
# 接着存到cookie
# response.set_cookie('uname', uname, max_age=30)
response.set_signed_cookie('conrent', uname, 'rock')
return response
def mine(request):
# 获取cookie
uname = request.COOKIES.get('content')
if uname:
return HttpResponse(uname)
# redirect是重定向简写,reverse是views中的反向解析
return redirect(reverse('app:login'))
对cookie解密
def mine(request):
# 获取cookie
# 解密
uname = request.get_signed_cookie('content', salt='rock')
if uname:
return HttpResponse(uname)
return redirect(reverse('app:login'))
实践:cookie退出登录
新建mine.html做一个网页用来退出登录
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>mine</title>
</head>
<body>
<h2>欢迎回来:{{ uname }}</h2>
<a href="{% url 'app:logout' %}">退出</a>
</body>
</html>
新建url
url('^logout/', views.logout, name='logout'),
views:我们将mine函数返回的httpresponse,改为返回html网页
def mine(request):
# 获取cookie
# uname = request.COOKIES.get('content')
uname = request.get_signed_cookie('content', salt='rock')
if uname:
return render(request, 'mine.html', context={'uname': uname})
# redirect是重定向简写,reverse是views中的反向解析
return redirect(reverse('app:login'))
# 退出就是让cookie消失,删除浏览器中的cookie,通过response让服务器
# 通知浏览器删除cookie
def logout(request):
response = redirect('app:login')
response.delete_cookie('content')
return response
可以观察到,通过设置了过期的cookie来达到删除cookie效果
优化:
当我们不携带cookie时去访问mine时会发现报错,因为获取不到content,这时候我们要提高兼容性
views:
def mine(request):
# 获取cookie
# uname = request.COOKIES.get('content')
try:
uname = request.get_signed_cookie('content', salt='rock')
if uname:
return render(request, 'mine.html', context={'uname': uname})
except Exception as e:
print('获取失败')
return redirect(reverse('app:login'))
问题怎么让cookie支持中文
base64
此处评论已关闭