网络之Cookie

1. 个性化服务

HTTP是无状态的请求/响应连接,导致连接断开后,再次连接服务器无法识别用户。
什么是无状态?
你先向服务器发送请求,建立TCP连接将请求发送过去,然后给我响应,TCP连接断开。在这一过程中没有做任何的保存,没有留下任何的痕迹。当你再一次访问的时候,需要重新的建立TCP连接,发送请求等操作。

2. 使用一些技术来帮助服务器去识别用户

方法一、跟踪客户端IP地址,但是很多地方的客户端都是动态的生成IP,因此服务器无法区分是不是同一个人。

方法二、借助http首部放置用户身份信息。如referer、e-mail。referer的用法是:大概可以知道是从哪一个相关的网站来的,然后可以推荐相关的信息。用e-mail不好之处是知道了用户的邮箱地址,然后可以给用户散发垃圾邮件。

方法三、胖URL(就是在URL后面添加许多许多的参数,导致URL会变得很长),在URL中嵌入识别信息(即通过URL中的参数信息识别是哪一个用户)。它的不好之处是比较丑陋,无法共享URL(因为每一个用户都会生成不同的URL),非持久(因为是放到URL连接中的,浏览器关闭之后,访问过的数据无法存储下来)等。

方法四、cookie(普遍采用它),在客户端存储用户标识信息。识别用户、持久化最好的方式。

3. Cookie原理(面试的时候很重要)

  1. 首次访问Web站点时,Web服务器对用户一无所知。Web服务器希望这个用户再次回来还能识别它。所以想给这个用户一个标识(相当于给它贴了一个标签:set-cookie:user_id=daipi173的响应首部)。
  2. 服务器返回响应的时候会带有响应首部set-cookie字段。浏览器会自动的把响应的cookie储存在浏览器数据库中(就是本地的文本文件,存储了一些cookie字段)。
  3. 当用户再次访问同一站点时,浏览器会把存储的cookie一起带上发送出去,这样服务器在拿到请求的同时也拿到这个cookie字段,知道以前你来过,然后会找与这个标签相对应的数据返回。

    4. Cookie分类

1.会话cookie(临时cookie),不设置过期时间,则表示这个cookie生命周期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。(用户退出浏览器时,会话cookie就被删除了,它是没有缓存时间的。)注意:会话cookie一般不保存在硬盘上而是保存在内存里。

2.持久cookie,存储在硬盘上,浏览器退出计算机重启时仍然存在。可以维护用户周期性访问的站点,它是有缓存时间的。
注意:设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie依然有效直到超过设定的过期时间。

存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存的cookie,不同的浏览器有不同的处理方式。

5. 认识Cookie属性

Cookie属性
1.Name:是Cookie的名称;
2.Value:是Cookie的值;
3.Domain:是可以访问该Cookie的域名(相同的域名或者父域下的所有子域都是可以访问的,如domain设置为baidu.com,那么baidu.com下的网页以及baidu.com下的子网页都可以访问到的);
4.Path:可以访问此Cookie的页面路径(如path是/abc,那么表示只有/abc路径下的页面可以读取此Cookie);
5.Expires/Max-Age:是用来设置时间的(之前的版本叫Expires,后来的版本叫Max-Age)不同浏览器表示的形式有可能是不一样的;
注意:只要时间是比当前时间靠前的cookie就是一个临时cookie。
6.Size:是Cookie的大小(注意:一般Cookie都是做标识的,因此它一般都比较小)
7.HTTP:Cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie;
8.Secure:设置是否只能通过https来传递此条cookie。

6. Cookie存储大小

由于cookie主要是用来标识的,因此不会太大,因此每一个浏览器设置的cookie大小大概是4K字节左右。

7. 客户端操作Cookie

cookie的增、删、改、查
例如:

  1. 增:
    1
    document.cookie = "user=12345";
  2. 删:
    方法一:可以人为的手动删除,我是拿的Chrome浏览器为例进行的手动删除,如下图所示:
    手动删除cookie
    方法二:将时间设置为当前时间的前一个时刻,就可以把设置的cookie删除
    1
    2
    3
    var oDate = new Date();
    oDate.setDate(oDate.getDate()-1); //只需要把时间设置在当前时间的前面,就可以把设置的cookie删除
    document.cookie = "user=12345;expires="+oDate;
  3. 改:
    1
    2
    // 假设cookie上面已经存在了一个“user=12345”的值,先来我们来对它进行一个修改
    document.cookie = "user=1111";
  4. 查:
    1
    document.cookie;

8. 自己手动封装了一个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
let manageCookie = {
setCookie: function(key,value,date){ // 增,改
let oDate = new Date();
oDate.setDate(oDate.getDate() + date);
document.cookie = `${key}=${value};expires=${oDate}`;
return this; // 返回this的作用是方便链式调用
},
removeCookie: function(key){ // 删
this.setCookie(key,"",-1);
return this;
},
getCookie: function(key,callback){ // 查
let allCookie = document.cookie;
let cookieArr = allCookie.split("; ");
cookieArr.forEach(function(ele){
let item = ele.split("=");
if(item[0] == key){
callback?callback(item[1]):"";
}
});
return this;
}
};
manageCookie.setCookie("name","daipi173",1).setCookie("age","22",1); // 链式调用增加了name和age两个cookie
manageCookie.removeCookie("name"); // 删除key为name的cookie
function cbs(key){
console.log(key);
}
manageCookie.getCookie("age",cbs); // 查找key为age的cookie