cookie实践

cookie实践

前面介绍了cookie和session的区别,这里读起来是有收获的,但是不做实验总是感觉很多东西浮在表面上,所以这里来做一下实验,看一下相应的知识点。

服务器搭建

这里使用最简单的node express,搭建一个简单的web服务器,相关命令如下:

mkdir cookie-test && cd cookie-test
npm init
npm install express --save
touch main.js

命令执行完成之后会发现已经有如下的结构出来,我们只需要编辑main.js即可:

cookie-test
|- main.js
|- node_modules
|- package.json

编辑代码,输入:

const express = require('express')
const app = express()

app.listen(3000, err => {
  if (err) {
    return console.log(err)
  }
  console.log('---- 打开 http://localhost:3000 吧----')
})

app.get('/', (req, res) => {
  res.send('<h1>hello world!</h1>')
})

这样就建立起一个简单的web服务器,我们来设置几个cookie看下。

cookie设置

在设置cookie前,我们先回顾一下cookie的工作原理:

1. 首先,我们假设当前域名下还是没有 Cookie 的
2. 接下来,浏览器发送了一个请求给服务器(这个请求是还没带上 Cookie 的)
3. 服务器设置 Cookie 并发送给浏览器(当然也可以不设置)
4. 浏览器将 Cookie 保存下来
5. 接下来,以后的每一次请求,都会带上这些 Cookie,发送给服务器

我们来验证一下,修改代码,加上下面的一行:

app.get('/', (req, res) => {
  res.cookie('key0', 'value0')
  res.send('<h1>hello world!</h1>')
})

重启服务器后看一下整个请求的过程:(https://i-blog.csdnimg.cn/blog_migrate/d43b3077adf9da4bc5ba5d8924edf957.jpeg “在这里输入图片标题”)
首次请求中在request中没有包括key0=value0的cookie,在response中带了key0的cookie,第二次请求后:
输入图片说明
已经带了key0的cookie。我们可以在console里看一下当前的cookie值,使用 document.cookie 就可以查看:
输入图片说明
确实已经有了key0的cookie。
下面总结一下什么是cookie:

1. Cookie 就是浏览器储存在用户电脑上的一小段文本文件
2. Cookie 是纯文本格式,不包含任何可执行的代码
3. Cookie 由键值对构成,由分号和空格隔开
4. Cookie 虽然是存储在浏览器,但是通常由服务器端进行设置
5. Cookie 的大小限制在 4kb 左右
cookie的属性

前面我们讲过,cookie的内容主要包括:名字,值,过期时间,路径和域,我们梳理一下前面的内容,做一个归纳总结:

1. cookie的内容主要包括:名字,值,过期时间,路径和域
2. 路径与域合在一起就构成了cookie的作用范围
3. 如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了

属性就是对自身包含的内容设置一些特殊参数的东西,比如什么时候过期等等,下面我们就来看cookie的属性。

expires / max-age

expires / max-age 都是控制 Cookie 失效时刻的选项。如果没有设置这两个选项,则默认有效期为 session,即会话 Cookie。这种 Cookie 在浏览器关闭后就没有了。

expires

expires 选项用来设置 Cookie 什么时间内有效,expires 其实是 Cookie 失效日期。
expires 必须是 GMT 格式的时间(可以通过 new Date().toGMTString() 或者 new Date().toUTCString() 来获得)
我们修改一下代码:

app.get('/', (req, res) => {
  res.cookie('key0', 'value0')
  res.cookie('key1', 'value1', {
            expires: new Date(Date.now() + 10000)
        })
  res.send('<h1>hello world!</h1>')
})

这里设置了10s的失效时间,我们来看一下实际运行的情况:
输入图片说明
发现已经设置了expire的过期时间,这时候在console里执行以下代码:

console.log(`现在的 cookie 是:${document.cookie}`)
setTimeout(() => {
  console.log(`5 秒后的 cookie 是:${document.cookie}`)
}, 5000)
setTimeout(() => {
  console.log(`10 秒后的 cookie 是:${document.cookie}`)
}, 10000)

观察到以下现象:
输入图片说明
10s之后,key1的cookie已经失效了。

max-age

expires 是 http/1.0 协议中的选项,在新的 http/1.1 协议中 expires 已经由 max-age 选项代替,两者的作用都是限制 Cookie 的有效时间。expires 的值是一个时间点 (Cookie 失效时刻 = expires),而 max-age 的值是一个以秒为单位时间段 (Cookie 失效时刻 = 创建时刻 + max-age)
当两者都存在的时候,以max-age的值为准:

res.cookie('key2', 'value2', {
        maxAge: 10000,
    })
    res.cookie('key3', 'value3', {
            maxAge: 15000,
            expires: new Date(Date.now() + 10000)
    })

我们看一下实际的运行效果:
输入图片说明

1. key1只有设置了expire,因此只有expire的值;
2. key2只有设置max-age,会默认把max-age和expire设置成一样的值;
3. key3 max-age和expire设置了不同的值,因此cookie里过期时间也不一样;

console运行之前的代码,修改打印cookie的时间,得出以下结果:
输入图片说明
这里console打印的内容没改,但是等待的时间已经变成10s 15s,分析一下上面的数据:

1. key2 max-age=10s,在10s后失效;
2. key3 expire=10s max-age=15s,在15s后失效,符合“以max-age的值为准”的结论;
domain 和 path

name、domain 和 path 可以标识一个唯一的 Cookie。domain 和 path 两个选项共同决定了 Cookie 何时被浏览器自动添加到请求头部中发送出去。
如果没有设置这两个选项,则会使用默认值。domain 的默认值为设置该 Cookie 的网页所在的域名,path 默认值为设置该 Cookie 的网页所在的目录。

secure

secure 选项用来设置 Cookie 只在确保安全的请求中才会发送。当请求是 HTTPS 或者其他安全协议时,包含 secure 选项的 Cookie 才能被保存到浏览器或者发送至服务器。
默认情况下,Cookie 不会带 secure 选项(即为空)。所以默认情况下,不管是 HTTPS 协议还是 HTTP 协议的请求,Cookie 都会被发送至服务端。

httpOnly

这个选项用来设置 Cookie 是否能通过 js 去访问。默认情况下,Cookie 不会带 httpOnly 选项(即为空),客户端是可以通过 js 代码去访问(包括读取、修改、删除等)这个 Cookie 的。当 Cookie 带 httpOnly 选项时,客户端则无法通过 js 代码去访问(包括读取、修改、删除等)这个 Cookie。
相应的实验可以通过设置

res.cookie('httpOnlyTest', 'testValue', {
            httpOnly: true
        })

来实验,会发现在console里打印cookie的时候没有httpOnlyTest这个cookie值。

关于domain和path

domain和path分别指代的是作用域和路径,我们先来看看域名的部分定义:

作用域
子域,是相对父域来说的,指域名中的每一个段。各子域之间用小数点分隔开。放在域名最后的子域称为最高级子域,或称为一级域,在它前面的子域称为二级域。

以下图为例,news.163.com 和 sports.163.com 是子域,163.com 是父域。
输入图片说明
当 Cookie 的 domain 为 news.163.com,那么访问 news.163.com 的时候就会带上 Cookie;
当 Cookie 的 domain 为 163.com,那么访问 news.163.com 和 sports.163.com 就会带上 Cookie

作用路径

当 Cookie 的 domain 是相同的情况下,也有是否带上 Cookie 也有一定的规则。
输入图片说明
在子路径内可以访问访问到父路径的 Cookie,反过来就不行。

明确一点:Cookie 可以由服务端设置,也可以由客户端设置。看到这里相信大家都可以理解了吧。

1. 一个 Set-Cookie 字段只能设置一个 Cookie,当你要想设置多个 Cookie,需要添加同样多的 Set-Cookie 字段
2. 服务端可以设置 Cookie 的所有选项:expires、domain、path、secure、HttpOnly

在网页即客户端中我们也可以通过 js 代码来设置 Cookie。
可以设置 Cookie 的下列选项:expires、domain、path,各个键值对之间都要用 ; 和 空格 隔开

document.cookie='name=value; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/';
secure

只有在 https 协议的网页中,客户端设置 secure 类型的 Cookie 才能成功

HttpOnly

客户端中无法设置 HttpOnly 选项

Cookie 的 name、path 和 domain 是唯一标识一个 Cookie 的。我们只要将一个 Cookie 的 max-age 设置为 0,就可以删除一个 Cookie 了。

let removeCookie = (name, path, domain) => {
  document.cookie = `${name}=; path=${path}; domain=${domain}; max-age=0`
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值