cookie和 session
cookie:
由于HTTP协议是无状态的。
无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。对服务器来说,每次的请求都是全新的。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就是这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此Cookie就是在这样一个场景下诞生。
首先来讲,cookie是浏览器的技术,Cookie具体指的是一段小信息,它是服务器发送出来存储在浏 览器上的一组组键值对,可以理解为服务端给客户端的一个小甜点,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
cookie的工作原理是:浏览器访问服务端,带着一个空的cookie,然后由服务器产生内容,浏览器收到相应后保存在本地;当浏览器再次访问时,浏览器会自动带上Cookie,这样服务器就能通过Cookie的内容来判断这个是“谁”了。
views页面
from django.shortcuts import render,redirect,HttpResponse from django.urls import reverse # Create your views here. def home(request): return render(request,'home.html') def login(request): if request.method == "GET": return render(request,'login.html') else: # 设置cookie if request.POST.get('username') == "root": ret = redirect(reverse('main')) ret.set_cookie('is_login',True) ret.set_cookie('name','root') return ret else: return render(request,'login.html') def outter(f): def inner(request, *args, **kwargs): if request.COOKIES.get('is_login'): res = f(request, *args, **kwargs) return res else: return redirect(reverse('login')) return inner @outter def main(request): return render(request,'main.html') @outter def cart(request): return render(request,'cart.html') # 删除cookie def logout(request): ret = redirect('login') ret.delete_cookie('is_login') return ret
获取cookie request.COOKIES.get('is_login') 设置cookie ret = redirect('/home/') #302 /home/ # ret = HttpResponse('ok') # ret = render(request,'home.html') # 设置cookie ret.set_cookie('is_login', True) ret.set_cookie('name', 'root') #设置同名的cookie,就是修改cookie return ret 设置签名cookie ret.set_signed_cookie('name', 'root',salt='sksk') 获取签名cookie request.get_signed_cookie('name',salt='sksk') #以防cookie在传输过程中被人修改了 删除cookie def logout(request): ret = redirect('login') ret.delete_cookie('is_login') return ret
设置cookie时的一些参数
参数: key, 键 value='', 值 max_age=None, 超时时间 值一个数字,单位是秒 expires=None, 超时时间(IE requires expires, so set it if hasn't been already.) 值是日期时间类型数据 path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 当:path='/index', 127.0.0.1:8001/home cookie 不生效,获取不到 127.0.0.1:8001/index/xxx/xx/ggg 生效,凡是访问/index路径下面的子路路径,都能获取到这个cookie domain=None, Cookie生效的域名 secure=False, https传输 httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
cookie值设置中文的方式
# 方式1 def login(request): ret = HttpResponse('ok') ret.set_cookie('k1','你好'.encode('utf-8').decode('iso-8859-1')) #取值:request.COOKIES['k1'].encode('utf-8').decode('iso-8859-1').encode('iso-8859-1').decode('utf-8') return ret 方式2 json def login(request): ret = HttpResponse('ok') import json ret.set_cookie('k1',json.dumps('你好')) #取值 json.loads(request.COOKIES['k1']) return ret
-
-
一个服务器最多在客户端浏览器上保存20个Cookie;
-
一个浏览器最多保存300个Cookie,因为一个浏览器可以访问多个服务器。
-
注意,不同浏览器之间是不共享Cookie的。也就是说在你使用IE访问服务器时,服务器会把Cookie发给IE,然后由IE保存起来,当你在使用FireFox访问服务器时,不可能把IE保存的Cookie发送给服务器。
针对以上特点cookie有数据大小限制,还明文存储在客户端,出现了session技术
session技术就是为了提升上面两个小缺陷。
session特点:
1.基于cookie时,也是以键值对的形式来存的数据,但是数据是密文的,只是一把钥匙(随机字符串)
2.真正的数据是保存在服务端的,将来通过cookie带过来的这个随机字符串,来找到服务端保存的对应用户的数据,数据既然是保存在服务端的,那么数据大小没有限制
from django.shortcuts import render,redirect,HttpResponse from django.urls import reverse # Create your views here. def home(request): return render(request,'home.html') def login(request): if request.method == "GET": return render(request,'login.html') else: # 设置cookie if request.POST.get('username') == "root": ret = redirect(reverse('main')) request.session['is_login'] = True request.session['uname'] = "root" return ret else: return render(request,'login.html') ''' request.session['is_login'] = True 做了三步事情 1. 生成一个随机字符串,并将这个字符串添加到了cookie里面,键值对名称这样的: sessionid:5eanp48ir6wugq8hohaiz57mlh4jdwdh 2. 将is_login和username这两个键值对数据{'is_login':True,'username':'root'}首先进行了json序列化,
然后进行了加密,然后将加密后的数据和sessionid对应的随机值保存到了django-sesison表中。 3. 给session保存的数据,加了有效期,默认是两周 ''' def outter(f): def inner(request, *args, **kwargs): if request.session.get("is_login"): res = f(request, *args, **kwargs) return res else: return redirect(reverse('login')) return inner ''' request.session['is_login'] 1.去cookie里面取出sessionid这个键对应的值(随机字符串) 2.通过这个随机字符串去django-session表里面获取对应的数据,session_data那一列的数据 3.对数据进行解密和反序列化,得到{'is_login':True,'username':'root'},然后通过键取出对应的值 ''' @outter def main(request): return render(request,'main.html') @outter def cart(request): return render(request,'cart.html') # 删除cookie def logout(request): request.session.flush() return redirect('login') ''' 1 删除cookie中的sessionid值 2 删除django-sesion表中保存的数据记录 '''
其他设置:
# 所有 键、值、键值对 request.session.keys() request.session.values() request.session.items() #获取sessionid的值 session_key = request.session.session_key # 设置会话Session和Cookie的超时时间 request.session.set_expiry(value) * 如果value是个整数,session会在些秒数后失效。 * 如果value是个datatime或timedelta,session就会在这个时间后失效。 * 如果value是0,用户关闭浏览器session就会失效。 * 如果value是None,session会依赖全局session失效策略。
session全局配置
1. 数据库Session SESSION_ENGINE = 'django.contrib.sessions.backends.db' # 引擎(默认) 2. 缓存Session SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 引擎 SESSION_CACHE_ALIAS = 'default' # 使用的缓存别名(默认内存缓存,也可以是memcache),此处别名依赖缓存的设置 3. 文件Session SESSION_ENGINE = 'django.contrib.sessions.backends.file' # 引擎 SESSION_FILE_PATH = None # 缓存文件路径,如果为None,则使用tempfile模块获取一个临时地址tempfile.gettempdir() 4. 缓存+数据库 SESSION_ENGINE = 'django.contrib.sessions.backends.cached_db' # 引擎 其他公用设置项: SESSION_COOKIE_NAME = "sessionid" # Session的cookie保存在浏览器上时的key,即:sessionid=随机字符串(默认) SESSION_COOKIE_PATH = "/" # Session的cookie保存的路径(默认) SESSION_COOKIE_DOMAIN = None # Session的cookie保存的域名(默认) SESSION_COOKIE_SECURE = False # 是否Https传输cookie(默认) SESSION_COOKIE_HTTPONLY = True # 是否Session的cookie只支持http传输(默认) SESSION_COOKIE_AGE = 1209600 # Session的cookie失效日期(2周)(默认) SESSION_EXPIRE_AT_BROWSER_CLOSE = False # 是否关闭浏览器使得Session过期(默认)
引入
<script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript" src="js/jquery.cookie.js"></script>
cookie操作
设置值: $.cookie('the_cookie', 'the_value'); # 设置7天有效期 $.cookie('the_cookie', 'the_value', { expires: 7 }); 读取cookie $.cookie('the_cookie'); #通过键来取值 删除cookie $.cookie('the_cookie', null); //通过传递null作为cookie的值即可