cookie
Cookie的由来
大家都知道HTTP协议是无状态的。
无状态的意思是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的请求响应情况。
一句有意思的话来描述就是人生只如初见,对服务器来说,每次的请求都是全新的。
状态可以理解为客户端和服务器在某次会话中产生的数据,那无状态的就以为这些数据不会被保留。会话中产生的数据又是我们需要保存的,也就是说要“保持状态”。因此cookie就是在这样一个场景下诞生。
什么是cookie
cookie翻译成中文意思是曲奇饼、饼干。然而,在因特网内cookie就和饼干没关系了。cookie具体指的是一段小信息,它是服务器发送出来存储在浏览器上的一组组键值对,下次访问服务器时浏览器会自动携带这些键值对,以便服务器提取有用信息。
简单的说,cookie是保存在浏览器上的键值对。服务端控制着响应,在响应里可以让浏览器在本地保存(键值对)cookie,下次请求在发送的时候就会自动携带这个cookie值。
备注:服务器端控制cookie是设置在一个响应对象上的,比如(ret= ‘redirect("/xx/"),ret.set_cookie’)
cookie默认关闭浏览器就失效。
查看cookie
我们使用Chrome浏览器,打开开发者工具。
Django中操作Cookie
获取Cookie
request.COOKIES['key']
request.get_signed_cookie(key, default=RAISE_ERROR, salt='', max_age=None)
参数:
- default: 默认值
- salt: 加密盐
- max_age: 后台控制过期时间
设置Cookie
rep = HttpResponse(...)
rep = render(request, ...)
rep.set_cookie(key,value,...)
rep.set_signed_cookie(key,value,salt='加密盐',...)
参数:
- key, 键
- value='', 值
- max_age=None, 超时时间
- expires=None, 超时时间(IE requires expires, so set it if hasn't been already.)
- path='/', Cookie生效的路径,/ 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问
- domain=None, Cookie生效的域名
- secure=False, https传输
- httponly=False 只能http协议传输,无法被JavaScript获取(不是绝对,底层抓包可以获取到也可以被覆盖)
备注:
set_cookie 和set_signed_cookie的一个小区别:set_cookie的设置失效时间max_age属性是在set_cookie里面,而且过期后会在浏览器端删掉设置的cookie(键值对),而set_signed_cookie中的设置失效时间max_age属性,可以设置在set_signed_cookie里面,也可以设置在get_signed_cookie里面(取的cookie时),而设置在get_signed_cookie里面时,失效后并不会在浏览器端删掉cookie值。因为失效是在服务端的接收时控制的。
还有,在发送POST请求时,我们是可以在if request.POST的条件中取到get的请求的(request.GET方法的使用的),而且在request的生命周期里,我们在视图函数和模板语言中,都可以取到request(也就是,都可以使用request的相关属性和方法 ),因为HTML页面的字符串替换是发生在服务器端的,切记!!
domain主要用于生效的域名,域名分为一级域名,二级域名,三级域名等等,按照( . )来区分,比如(jd.com(一级域名)和miaosha.jd.com(二级域名))
删除Cookie
主要用于注销函数的使用:
def logout(request):
rep = redirect("/login/")
rep.delete_cookie("user") # 删除用户浏览器上之前设置的usercookie值
return rep
Cookie版登陆校验
def check_login(func): @wraps(func) def inner(request, *args, **kwargs): next_url = request.get_full_path() if request.get_signed_cookie("login", salt="SSS", default=None) == "yes": # 已经登录的用户... return func(request, *args, **kwargs) else: # 没有登录的用户,跳转刚到登录页面 return redirect("/login/?next={}".format(next_url)) return inner def login(request): if request.method == "POST": username = request.POST.get("username") passwd = request.POST.get("password") if username == "xxx" and passwd == "dashabi": next_url = request.GET.get("next") if next_url and next_url != "/logout/": response = redirect(next_url) else: response = redirect("/class_list/") response.set_signed_cookie("login", "yes", salt="SSS") return response return render(request, "login.html")