day74 cookie
Cookie 与 Session的会话跟踪技术:
HTTP协议是无状态保存协议。所以每次请求都是独立的,无法记录前一次请求的状态。但HTTP协议中可以使用Cookie来完成会话跟踪。
在web开发中主要用session来完成会话跟踪技术,Session底层是依赖Cookie技术。
Cookie 概述:
(1)Cookie是一种key-value结构,类似于一个python中的字典,
(2)随着服务器端的响应发送给客户端浏览器,然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时,把Cookie再发送给服务器。
(3) Cookie是由服务器创建通过响应以键值对的形式发送给客户端浏览器。客户端会保存cookie并注明cookie的来源(哪个服务器的cookie)。
(4)当客户端向服务器发送请求时会把这个服务器的所有cookie和请求打包一起发给服务器。这样服务器就可以识别客户端了。
配图一份:
Cookie规范:
(1) cookie大小上限是4KB
(2) 一个服务器最多在客户端浏览器上保存20个cookie;
(3) 一个浏览器最多保存300个cookie;
Cookie 与 HTTP头:
cookie是通过HTTP请求和响应头在服务器端和客户端之间进行传递的。
(1)cookie:请求头:客户端发送给服务器端。
(2) 格式:a = A,;b = B; c = C 即:多个cookie用分号分割开
(3) set-cookie :响应头服务器端发送给客户端
(4) 一个cookie对象,一个set-cookie
Set-Cookie:a = A
Set-Cookie:b = B
Set-Cookie:c = C
Cookie的覆盖:
如果服务器端发送重复的cookie,那么会覆盖原有的cookie.
例如客户端的第一个请求服务器端发送的Cookie是:Set-Cookie: a=A;第二请求服务器端发送的是:Set-Cookie: a=AA,那么客户端只留下一个Cookie,即:a=AA。
Django 中 Cookie的使用:
(1)设置cookie:
# 获得 响应对象
ret = HttpResponse('') 或 ret = render(request,'login.html') 或 ret = redirect(reverse('别名'))
# 设置cookie 值
ret.set_cookie(key,value,……) # 不加密的方式,不推荐使用
ret.set_signed_cookie(key,value,salt = '加密盐',……) # 加密方式,推荐使用
源码:
''' class HttpResponseBase: def set_cookie(self, key, 键 value='', 值 max_age=None, 超长时间
cookie需要延续的时间(以秒为单位)
如果参数是\ None`` ,这个cookie会延续到浏览器关闭为止。
expires=None, 超长时间
expires默认None ,cookie失效的实际日期/时间。
path='/', Cookie生效的路径, 浏览器只会把cookie回传给带有该路径的页面,这样可以避免将 cookie传给站点中的其他的应用。 / 表示根路径,特殊的:根路径的cookie可以被任何url的页面访问 domain=None, Cookie生效的域名 你可用这个参数来构造一个跨站cookie。 如, domain=".example.com" 所构造的cookie对下面这些站点都是可读的: www.example.com 、 www2.example.com 和an.other.sub.domain.example.com 。 如果该参数设置为 None ,cookie只能由设置它的站点读取。 secure=False, 如果设置为 True ,浏览器将通过HTTPS来回传cookie。 httponly=False 只能http协议传输,无法被JavaScript获取 (不是绝对,底层抓包可以获取到也可以被覆盖) ): pass '''
参数:
参数:
- 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获取(不是绝对,底层抓包可以获取到也可以被覆盖)
复制代码 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")
(2)获取cookie:
request.COOKIES
(3)删除cookie:
request.delete_cookie('cookie_key')
练习
案例1:显示上次访问时间。
案例2:显示上次浏览过的商品。