详情请点阅读全文
一.状态保持的概述
http协议是无状态的。下一次去访问一个页面时并不知道上一次对这个页面做了什么。因此引入了cookie、session两种方式来配合解决此问题。
Duplicate entry:重复条目
二、Cookie(存储在客户端)
- cookie是由服务器生成,存储在浏览器端的一小段文本信息。
1.1 cookie的特点:
0) 服务器通过HttpRessponse的对象set_cookie设置cookie:HttpRessponse.set_cookie
1) 浏览器以键值对方式进行存储。
2) 通过浏览器访问一个网站时,会将浏览器存储的跟网站相关的所有cookie信息发送给该网站的服务器。(服务器取cookies:request.COOKIES
)
3) cookie是基于域名安全的。www.baidu.com www.tudou.com
4) cookie是有过期时间的,如果不指定,默认关闭浏览器之后cookie就会过期。1.2 cookie基础使用案例
1)app1/views.py编写设置cookie设置/获取函数
1.设置cookie:/setCookie
2.获取cookie:/getCookie
1 2 3 4 5 6 7 8 9 10 11 12
| def set_cookie(request): '''请求设置cookie''' response=HttpResponse('设置cookie') response.set_cookie('name','jim') return response
def get_cookie(request): '''服务器获取浏览器的cookie''' name=request.COOKIES['name'] return HttpResponse(name)
|
2)配置app1/urls.py
设置cookie页
获取cookie页
1 2 3 4 5
| from django.urls import path,re_path from . import views
re_path('^setCookie$',views.set_cookie), re_path('^getCookie$',views.get_cookie),
|
效果:
显示:设置cookie
返回头将看到:set-Cookie:name=jim; path=/
显示jim,请求头里有个信息即发送给服务器的cookieCookie:sessionid=5pvq8zmkgtb9omarod4q52lhfsmcc5sp; csrftoken=hW4qfF5faVmg60G1RRf7KCL8ZuwnA0OR7OqYpufJedQOGY3IZKaZmS6EXbLfbk8j; name=jim
关闭浏览器之后,再请求cookie即找不到之前设置的cookie,因为没指定时间,所以用默认设置,关闭即过期:
http://127.0.0.1:8000/getCookie
3)设置cookie过期时间views.py
- 设置过期方式一 【max_age】(单位:秒):
max_age=14*24*3600
14天后过期
- 设置过期方式二 【expires】 (单位:时间):
expires=datetime.now()+timedelta(days=14)
14天后过期1 2 3 4 5 6 7 8 9 10 11 12 13 14
| from django.shortcuts import render,redirect from django.http import HttpResponse,JsonResponse from datetime import datetime,timedelta
def set_cookie(request): '''设置cookie信息''' response = HttpResponse('设置cookie') response.set_cookie('num', 1, max_age=14*24*3600) return response
|
再设置时会看到一个14天的日期
以后14天内这个cookie都会存在 。
4) 设置多个cookie
1 2 3 4 5 6 7 8 9 10
| def set_cookie(request): '''请求设置cookie''' response=HttpResponse('设置cookie') response.set_cookie('name','jim',max_age=14*24*3600) response=HttpResponse('设置cookie2') response.set_cookie('age',20,max_age=15*24*3600) return response
|
1.3 记住用户名案例
1)templates/app1/login.html
【1】添加记住用户名,设置cookie用,如果勾选则其value=on
【2】js添加是否记住用户名
【3】js添加发送数据,加上remember
【4】把views页的login()函数传过来的用户名,密码赋值给对应处
用户名:<input type="text" id="username" value=""><br/>
密码:<input type="password" id="password" value=""><br/>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <!-- 【0】引入jquery --> <script src="/static/js/jquery-1.12.4.min.js"></script> <title>登录页面</title> </head> <script> // 写ajax处理函数 $(function () { $('#btnLogin').click(function () { //1.获取用户名、密码、是否记住用户名 username=$('#username').val() password=$('#password').val() remember=$('#remember').val() //【2】是否记住用户名 //2.发起ajax--post(username,password)请求验证,地址:/login_check $.ajax({ 'url':'/login_check',//验证地址 'type':'post',//请求类型 'data':{'username':username,'password':password,'remember':remember},//【3】发送数据,加上remember 'dataType':'json',//希望返回数据类型 }).success(function(data){ //成功返回{'res':1},失败{'res':0} if(data.res===0){ $('#msg').show().html('用户名或密码错误请重试!')//登录失败则显示msg,并在里写入信息 }else{//成功跳转到books页面 location.href='/books' } })
}) }) </script> <style> /* 信息提示样式 */
display: none; color:red; } </style> <body> <!-- 原form删除,input的name变id,方便jquery操作 --> <!-- 【4】把views页的login()函数传过来的用户名,密码赋值给对应处 --> 用户名:<input type="text" id="username" value="{{username}}"><br/> 密码:<input type="password" id="password" value="{{password}}"><br/> <!-- 加入一个信息提示框,用于密码等错误提示 --> <div id="msg"></div> <!-- 【1】记住用户名,设置cookie用,如果勾选则其value=on --> <input type="checkbox" id="remember">记住用户名<br/> <!-- 按钮type改button,加一个id方便jquery操作 --> <input type="button" id="btnLogin" value="登录">
</body> </html>
|
2)app1/urls.py(不重要)
【1】登录页
【2】登录检测
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| from django.urls import path,re_path from . import views
urlpatterns=[ path('login/',views.login), path('login_check',views.login_check),
re_path('^setCookie$',views.set_cookie), re_path('^getCookie$',views.get_cookie),
path('app1/',views.index), path('books/',views.books),
re_path(r"^detail/(\d+)",views.detail),
path('addInfo/',views.addInfo),
path(r'delete/<int:bid>',views.deleteInfo),
path(r'areas/',views.areas),
path(r'test_ajax',views.test_ajax), path(r'ajax_handle/',views.ajax_handle),
]
|
3)app1/views.py【重点】
【1】接收remeber
【2】正确返回1,重写
【3】如果remember==on,则把用户名,密码设置cookie到cookie
【4】不要忘记返回response
【5】如果用户名密码已经在cookie中,则取到它,并做为参数返回给渲染页面
[6]获取cookie中的用户名、密码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| from django.shortcuts import render,redirect from app1.models import BookInfo,AreaInfo from django.http import HttpResponse,HttpResponseRedirect,JsonResponse from datetime import datetime,timedelta
def login(request): '''登录页''' if 'username' in request.COOKIES: username=request.COOKIES['username'] password=request.COOKIES['password'] else: username='' password='' return render(request,'app1/login.html',{'username':username,'password':password})
def login_check(request): '''登录校验''' username=request.POST.get('username') password=request.POST.get('password') remember=request.POST.get('remember') if username=='jim' and password=='123': response = JsonResponse({'res':1}) if remember=='on': response.set_cookie('username',username,max_age=7*24*3600) response.set_cookie('password',password,max_age=7*24*3600) return response else: return JsonResponse({'res':0})
|
如果勾选上记住用户名,提交时会让/login_check处理,把用户名、密码的cookie设置到浏览器,
再次来到login页面时,用户名密码会通过templates/login页里的变量直接赋值到对应处,从而实现免填密码登录。
三、Session(存储在服务器端)
session存储在服务器端。
1 配置
启用Session
Django项目默认启用Session。
打开test3/settings.py文件,在项MIDDLEWARE_CLASSES中启用Session中间件。
session中间件
禁用Session:将Session中间件删除。
存储方式
打开test3/settings.py文件,设置SESSION_ENGINE项指定Session数据存储的方式,可以存储在数据库、缓存、Redis等。
1)存储在数据库中,如下设置可以写,也可以不写,这是默认存储方式。
SESSION_ENGINE=’django.contrib.sessions.backends.db’
2)存储在缓存中:存储在本机内存中,如果丢失则不能找回,比数据库的方式读写更快。
SESSION_ENGINE=’django.contrib.sessions.backends.cache’
3)混合存储:优先从本机内存中存取,如果没有则从数据库中存取。
SESSION_ENGINE=’django.contrib.sessions.backends.cached_db’
4)如果存储在数据库中,需要在项INSTALLED_APPS中安装Session应用。
5)迁移后会在数据库中创建出存储Session的表。
存储session
6)表结构如下图。
存储session表结构
由表结构可知,操作Session包括三个数据:键,值,过期时间。
2 使用方法:
1.设置:session:request.session['username']='jim'
2.获取:session:request.session['username']
3.清除所有session,在存储中删除值部分。
4. 清除session数据,在存储中删除session的整条数据。
5. 删除session中的指定键及值,在存储中只删除某个键及对应的值。
1
| del request.session['键']
|
6.设置会话的超时时间,如果没有指定过期时间则两个星期后过期。
request.session.set_expiry(value)
- 如果value是一个整数,会话将在value秒没有活动后过期。
- 如果value为0,那么用户会话的Cookie将在用户的浏览器关闭时过期。
- 如果value为None,那么会话永不过期。
3.1 session的特点:
1) session是以键值对进行存储的。
2) session依赖于cookie。唯一的标识码保存在sessionid cookie中。
3) session也是有过期时间,如果不指定,默认两周就会过期。
4. 保存的是字符串,得到就是字符串,是数字,得到即数字。
5. session保存位置:对应数据库的表 django_session
6.
7.
3.2 session基本设置、获取、清除案例
1)app1/views.py
设置session过期时间
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| def set_session(request): '''设置session''' request.session['username'] = 'smart' request.session['age'] = 18 return HttpResponse('设置session')
def get_session(request): '''获取session''' username = request.session['username'] age = request.session['age'] return HttpResponse(username+':'+str(age))
def clear_session(request): '''清除session信息''' request.session.flush() return HttpResponse('清除成功')
|
2)app1/urls.py
1 2 3
| re_path('^setSession$',views.set_session), re_path('^getSession$',views.get_session), re_path('^clearSession$',views.clear_session),
|
扩展:session的数据库保存值是base64编码
可在百度搜索 【base64解码】,查看其保存具体信息
https://base64.supfree.net/
3.3 记住用户登录状态案例
1)app1/views.py编写登录函数:设置session,读取session
【1】如果用户勾选了remember的条件下,设置session,记住用户登录状态
【2】判断用户是否登录,用户已登录, 直接跳转到图书列表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| from django.shortcuts import render,redirect from app1.models import BookInfo,AreaInfo from django.http import HttpResponse,HttpResponseRedirect,JsonResponse from datetime import datetime,timedelta
def login(request): '''登录页''' if request.session.has_key('islogin'): return redirect('/books') else: if 'username' in request.COOKIES: username=request.COOKIES['username'] password=request.COOKIES['password'] else: username='' password='' return render(request,'app1/login.html',{'username':username,'password':password})
def login_check(request): '''登录校验''' username=request.POST.get('username') password=request.POST.get('password') remember=request.POST.get('remember') if username=='jim' and password=='123': response = JsonResponse({'res':1}) if remember=='on': response.set_cookie('username',username,max_age=7*24*3600) response.set_cookie('password',password,max_age=7*24*3600)
request.session['islogin'] = True return response else: return JsonResponse({'res':0})
|
2)app1/urls.py
1 2 3 4 5 6 7
| from django.urls import path,re_path from . import views
urlpatterns=[ path('login/',views.login), path('login_check',views.login_check), ]
|
3)templates/app1/login.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
| <!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <!-- 【0】引入jquery --> <script src="/static/js/jquery-1.12.4.min.js"></script> <title>登录页面</title> </head> <script> // 写ajax处理函数 $(function () { $('#btnLogin').click(function () { //1.获取用户名、密码、是否记住用户名 username=$('#username').val() password=$('#password').val() remember=$('#remember').val() //【2】是否记住用户名 //2.发起ajax--post(username,password)请求验证,地址:/login_check $.ajax({ 'url':'/login_check',//验证地址 'type':'post',//请求类型 'data':{'username':username,'password':password,'remember':remember},//【3】发送数据,加上remember 'dataType':'json',//希望返回数据类型 }).success(function(data){ //成功返回{'res':1},失败{'res':0} if(data.res===0){ $('#msg').show().html('用户名或密码错误请重试!')//登录失败则显示msg,并在里写入信息 }else{//成功跳转到books页面 location.href='/books' } })
}) }) </script> <style> /* 信息提示样式 */
display: none; color:red; } </style> <body> <!-- 原form删除,input的name变id,方便jquery操作 --> <!-- 【4】把views页的login()函数传过来的用户名,密码赋值给对应处 --> 用户名:<input type="text" id="username" value="{{username}}"><br/> 密码:<input type="password" id="password" value="{{password}}"><br/> <!-- 加入一个信息提示框,用于密码等错误提示 --> <div id="msg"></div> <!-- 【1】记住用户名,设置cookie用,如果勾选则其value=on --> <input type="checkbox" id="remember">记住用户名<br/> <!-- 按钮type改button,加一个id方便jquery操作 --> <input type="button" id="btnLogin" value="登录">
</body> </html>
|
- 第一次登录勾选记住用户名密码后
- 再访问登录页时,将自动跳转到:http://127.0.0.1:8000/books
3.4 cookie和session的应用场景
- cookie:记住用户名。安全性要求不高。
- session:涉及到安全性要求比较高的数据。银行卡账户,密码