cookie.md

客户端存储之cookie

什么是cookie和为什么有cookie

  • 什么是cookie

cookie是指web浏览器存储的少量数据(注意:这些数据是由服务器给浏览器的,然后由浏览器存储保管)。这些数据是与你访问的页面或站点相关的

  • 为什么会有cookie

首先我们应该知道——HTTP协议是无状态的

什么是协议的状态——协议的状态是指:下一次传输可以记住上一次传输的信息的能力。从传统WEB上看:无状态是指,当浏览器发送请求给服务器的时候,服务器响应,但是同一个浏览器再发送请求给服务器的时候,他会响应,但是他不知道你就是刚才那个浏览器,简单地说,就是服务器不会去记得你,所以是无状态协议。本质是:HTTP1.0是短连接的(这里先忽略HTTP1.1的keep alive吧),请求响应后,断开了TCP连接,下一次连接与上一次无关

然后,为了识别不同的请求是否来自同一客户(或者说间接地使HTTP协议有状态),便引入了HTTP会话机制

而cookie就是实现会话的一种机制(因此,cookie实际上存储的是会话信息)

会话就是:TCP的三次握手就创建了一个会话,TCP关闭连接就是关闭会话,这就是一次会话

cookie是怎么工作的

cookie标准要求服务器对任意HTTP请求发送Set-Cookie头,作为响应的一部分

在这里插入图片描述

浏览器会存储这些会话信息,并在之后访问相同的页面或站点时,通过为每个请求添加Cookie头,将上一次存储的会话信息返回给服务器

在这里插入图片描述

服务器端脚本读取返回的Cookie信息,并作出相关响应

这样通过cookie便间接地使HTTP有了状态

我们平时都见过,登录时自动记录账号。我们就以此为例,来阐述cookie的工作流程:

注:每一个小圆点,就代表一步

  • 当你填好用户名与密码后,点击登录按钮,向服务器发出一个登录请求
  • 服务器收到请求,并创建一个保存了用户名和其他与本次请求相关的状态信息的cookie,然后将该cookie信息放入响应头中,并与响应体一同传回给浏览器(响应头中的Set-Cookie即为浏览器传回的cookie)
  • 浏览器读取响应头中的cookie信息,并以文本文件的形式保存到计算机中(前提是浏览器允许保存cookie信息)
  • 下一次你再访问本登录页面时,浏览器自动将对应的保存在本地的cookie信息取出,并以请求头的形式发送给服务器(请求头中的Cookie即为发送的cookie),然后服务器返回的登录页中的脚本会读取cookie中的用户名信息,将其设置在输入框中(这一步我不太确定想的是否正确)

在这里插入图片描述

注意:cookie由服务器端设置,保存在客户端

如果你还是疑惑,可以参考这篇文章:
https://www.cnblogs.com/andy-zhou/p/5360107.html

cookie的组成

这儿先用一张图展示(chrome浏览器中展现的)cookie的组成部分

在这里插入图片描述

  • Name与Value

这个很好理解,Name对应该cookie的名,Value对应该cookie的值(似乎有点废话)。如:

document.cookie = 'age=19';

中‘age’对应Name,19对应Value

  • Domain(域名)

用于确定该cookie对于哪些域是有效的。所有向这些域发送的请求都会包含这个cookie信息(当然:Path也要允许才行)。该值可以是子域(如:www.baidu.com),也可以是父域(如:baidu.com——则该cookie对于其下所有的子域都有效)。如果没有明确的设定,那么这个域默认为设置cookie的那个域

子域能访问父域的cookie,父域不能访问子域的cookie;同级的域之间也不能互相访问各自的cookie

cookie满足同源策略

  • Path(路径)
    设置cookie路径,从而确定域中的哪些路径应该像服务器发送cookie。(实际同Domain差不多)

默认为当前文件位于服务器中的路径(即url中域名后面由‘/’展现的路径——默认状态),可以人为修改默认值

注意:

子路径(目录)可以访问祖先路径(目录)中的cookie,而祖先路径(目录)不能访问子路径(目录)中的cookie
而判断是子路径还是祖先路径。需根据path的值,而无论在文件夹中的实际位置如何
如:
D:\wampserver\wamp\www\temp.html(默认path为/)
document.cookie = ‘age=19’;
D:\wampserver\wamp\www\test\temp.html(默认path为/test)
document.cookie = ‘name=德洛丽丝’;
现在我们采用path的默认路径。问,在test下的temp.html中能访问www下的temp.html的cookie吗?
我们先运行www文件夹下的temp.html,再运行test下的temp.html,你会发现test下的temp.html有两个cookie,其中一个即为来自www下temp.html的cookie

  • Expires/Max-Age

设置cookie的删除时间。默认情况下——在浏览器会话结束时即将所有cookie删除(‘会话’前面已经说了)。也可自己设置(这个值是GMT格式——Wdy, DD-Mon-YYYY HH:MM:SS GMT——通过Date对象中的toUTCString()方法)

值为负数时,表示关闭窗口后cookie即失效(此时cookie存在于内存中,不会被写入本地文件);值为0表示不保存该cookie,立即删除。设置的是以前的时间,cookie也会立即删除

因此,我们常常设置这个属性的值为0或负数来达到删除cookie的操作

尤其注意:除了Name、Value以外的像Domain、Path等其它组成部分都是服务器给浏览器的关于本次cookie的描述。因此,这些参数并不会作为Cookie头的一部分由浏览器发送给服务器。只有名值对才会发送给服务器

使用JS脚本操作cookie

主要就是cookie的增、删、改、查

使用‘document.cookie’来增添cookie

<script>
    document.cookie = 'name=德洛丽丝';
    document.cookie = 'age=19';
</script>

在这里插入图片描述

关于增操作需要注意的地方:

  1. 当我们要设置多个cookie时,需要多次‘document.cookie’,不能一次性全设置,例如这样
document.cookie = 'age=19;name=德洛丽丝';//这是错误的

要是以这种错误的方式设置,则结果便是下面这样

在这里插入图片描述

可见,只有age被设置上了。这是因为,在设置cookie时,只会将第一个等式视为cookie,后面的等式都视为描述此cookie的属性(当然,以为是自定义的,所以这些属性不会被展现,实际可能根本不会被设置为属性,这个我也不太清楚)

  1. 相同的cookie,会值覆盖,不同的cookie不会值覆盖。如下:
<script>
    document.cookie = 'name=德洛丽丝';
    document.cookie = 'name=伯纳德';
</script>

在这里插入图片描述

那什么样的cookie才算是不同的cookie呢?只要‘Name、Domain、Path’这几个属性只要有一个不同,则cookie不同(三个属性都相同cookie才相同)。下面一一为你展现,这几个属性不同时的结果
在这里插入图片描述
在这里插入图片描述
关于Domain不同,无法演示,因为跨域了。。。
上述只是现象,关于背后的原因会在介绍‘Domain、Path’两个属性时叙述,你只需要记住什么情况下cookie不同就行了

3.在设置cookie时最好使用encodeURIComponent()编码,获取时再使用decodeURIComponent()解码

document.cookie=encodeURIComponent('name')+'='+encodeURIComponent('德洛丽丝');

  • cookie并不提供删除操作,因此若想删除某个cookie,则需要使用增添操作,添加一个‘相同的cookie’(Domain、Path、Name相同)并将其中的max-age设为0或负数。如:
document.cookie = 'name=德洛丽丝';
setTimeout(function(){
    document.cookie = 'name=德洛丽丝;max-age=-1';
}, 1000);
//document.cookie = 'name=德洛丽丝;max-age=-1';或者直接这样删除(不用点击刷新按钮)

上述添加了一个cookie、1s后将该cookie删除

注意:这种删除方式需要你点击一下控制台的刷新按钮,不然cookie会一直显示出来,实际上你已经删除了


  • cookie并不提供改操作,因此若想修改某个cookie,则需要使用增添操作,添加一个‘相同的cookie’(Domain、Path、Name相同),但值不同
document.cookie = 'name=德洛丽丝';
setTimeout(function(){
    document.cookie = 'name=伯纳德';
}, 1000);

注意点击刷新按钮


  • cookie并不提供查操作,因此你需要将本页面对应的所有cookie读出来(结果是字符串),然后对字符串进行处理,以提取cookie的值

直接使用‘document.cookie’便可以读取所有cookie

document.cookie = 'name=德洛丽丝';
    document.cookie = 'age=30';
    document.cookie = 'sex=女';

    var cookieStr = document.cookie;//"name=德洛丽丝; age=30; sex=女"
    var cookieArr = cookieStr.split('; ');
    console.log(cookieArr[0].split('=')[0] + ':' + cookieArr[0].split('=')[1]);

cookie增、删、改、查操作的封装

var cookieOperation = {
    add : function(name, value, time){//增或改
        document.cookie = name + '=' + value + ';max-age=' + time;
        return this;
    },
    check : function(name){
        var cookieStr = document.cookie,
            cookieArr = cookieStr.split('; '),
            len = cookieArr.length;
        for(var i = 0; i < len; i++){
            if(cookieArr[i].split('=')[0] === name){
                return cookieArr[i].split('=')[1];
            }
        }
    },
    remove : function(name){
        return cookieOperation.add(name, '', 0);
    }
};

cookie与web存储的比较

在这里插入图片描述

关于cookie的作用域与有效期是由path/domain、max-age决定的,文中也说了。更权威的可看
《JavaScript权威指南》——20.2.1节

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值