Cookie是什么
具体定义百度一大堆,这里说通俗点,就可以把Cookie理解成保存在客户端,也就是浏览器端的键值对,
服务端可以通过设置Cookie的方式,在浏览器端保存键值对数据,例如用户的用户名,密码等等信息,
这样下次浏览器在访问服务端时,就可以直接带着这个Cookie去通过服务端的验证,这样就达到了服务器端好像记住了
用户的机器一样,有了记忆功能
我们结合以前所说的Django知识来写个小的学生登录系统,来更好的学习Cookie
学生登录系统
没Cookie版
### views.py ####
from django.shortcuts import render
# Create your views here.
from blog.models import *
from django.http import HttpResponse
def index(req):
pass
def login(req):
if req.method == "POST":
username = req.POST.get("username")
password = req.POST.get("password")
if username=='R0' and password=='123':
return HttpResponse("Hello"+username)
return render(req,'login.html')
#urls.py##
urlpatterns = [
path('admin/', admin.site.urls),
url('index',views.index),
url('login',views.login),
]
login.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
姓名:<input type="text" name="username">
<br>
密码:<input type="text" name="password">
<br>
<input type="submit" value="登录">
</form>
</body>
</html>
这样我们就写好了一个没有使用Cookie的学生登录系统
下面我们就给它加上Cookie
Cookie版
from django.shortcuts import render,redirect
# Create your views here.
from blog.models import *
from django.http import HttpResponse
def index(req):
username = req.COOKIES.get("username")
if username:
return render(req,"index.html",{"username":username})
return redirect("/login")
def login(req):
msg = ' '
if req.method == "POST":
username = req.POST.get("username")
password = req.POST.get("password")
if username=='R0' and password=='123':
obj = redirect("/index")
obj.set_cookie("username",username)
return obj
msg = "密码错误"
return render(req,'login.html',{"msg":msg})
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Hello {{ username }}</h1>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="/login" method="post">
姓名:<input type="text" name="username">
<br>
密码:<input type="text" name="password">
<br>
<input type="submit" value="登录">{{ msg }}
</form>
</body>
</html>
我们实际上就是用了
set_cookie函数写入了一组键值对,浏览器端收到服务器端发来的响应之后,就会自动在本地将Cookie信息写下来
下次在访问时会自动把Cookie信息带着,服务器端就可以从Cookie中读取信息,达到“记忆”的目的
谷歌浏览器中,我们按F12进入开发者工具
可以查看该站点的Cookie信息
Cookie的几个性质
由于Cookie就是浏览器端的几组键值对,所以Cookie有几个性质
1、保存在用户浏览器
2、可以主动清除 跟删除历史记录一个操作
3、也可以被“伪造”
4、跨域名cookie不共享
5、浏览器设置不接受cookie
set_cookie设置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获取(不是绝对,底层抓包可以获取到也可以被覆盖)
max_age默认是以秒为单位。描述cookie在多少秒之后过期 eg:
obj.set_cookie("username",username,max_age=5)
设置之后。此cookie将在5秒之后过期
expires也是设置过期时间,不过这个是个datatime对象,用法如下
timeout = datetime.datetime.utcnow()+ datetime.timedelta(seconds=10) obj.set_cookie("username",username,max_age=5,expires=timeout)
首先获取当前的UTC时间,然后加时间差
如果max_age和expires都已经设置的话,以expires为准
path表示设置的这个Cookie对哪个URL生效,可以假想浏览器为每个二级域名设置了一个大盒子
ps:什么是二级域名,像www.msl.com这就是二级域名 crm.msl.com也是二级域名 msl.com是一级域名
如果path设置的是/意味着在当前的二级域名下写一个全局cookie,每个url可以看成是这个大盒子里面的小盒子
我们可以在当前的二级域名下随便设置cookie 但是我们无法跨二级域名设置cookie
在domain中我们可以指定msl.com 这样就在一级域名里设立了cookie 这样两个二级域名都可以访问到这个cookie
大盒子里的Cookie优先级是大于小盒子里的Cookie的,浏览器会优先找大盒子里的
写Cookie时如果键值已经存在,而且盒子也相同,会覆盖掉上个值
可以做实验具体操作一下
还可以用这个函数写加密的Cookie
rep.set_signed_cookie(key,value,salt
=
'加密盐'
,...)
读取时用
request.get_signed_cookie(key, default
=
RAISE_ERROR, salt
=
'', max_age
=
None
)