amandakelake / blog

think more!learn more!

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

cookie实践(从搭建服务器到cookie操作全流程)

amandakelake opened this issue · comments

commented

看了很多关于cookie与session的理论文章,项目中日常也经常用,但自己是前端er,对后端一直抱有好奇心,这次就拿cookie开到,跑一个全流程吧,也顺便作为巩固cookie知识的一个实践

COOKIE和SESSION有什么区别? - 知乎

搭建服务器,初始化

通过node,我们可以很轻易的搭建出一个本地服务器,也为我们做各种项目试验带来了方便,再次推崇一发node大法

mkdir cookie-dome
cd cookie-dome
npm init
npm i express --save
touch main.js

这里使用了express框架快速搭建服务器,在新建的main.js文件输入以下代码
express中文官网

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

app.get('/',(req, res) => {
  res.send('Hello cookie-demo')
});

app.listen(3000,() => {
  console.log('Example app listening on port 3000!');
})

终端输入node main.js把服务器跑起来
浏览器输入http://localhost:3000即可看到如下界面

ba9b2cc2-3baa-42a7-9fbf-5dd0c812834a

还可以看到,页面已经有了一个请求,但没有cookie相关的信息

cookie工作方式

忘了哪位伟人说过:大胆假设,小心验证,那我们就听一次话吧
先猜测大概流程如

假设如下
  • 1、当前没有cookie
  • 2、浏览器干啥都不会跟cookie有关系,服务器也不会跟cookie有关系
  • 3、某天,服务器发现:”哎,每次都不知道这小子是谁,给它加个身份吧“,然后发送了一个cookie给浏览器,”兄弟,你记一下这个暗号,以后每次向我请求就带上这个东西,以后我就记得住你是谁了“,这称之为setcookie
  • 4、浏览器收到后,就把这个cookie记下来了
  • 5、以后每次浏览器请求都会带上这个cookie
开始验证

main.js文件中加上res.cookie('cookie1', 'cookie1')

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

app.get('/',(req, res) => {
  res.cookie('cookie1', 'cookie1')//这里加上
  res.send('Hello cookie-demo')
});

app.listen(3000,() => {
  console.log('Example app listening on port 3000!');
})

关闭服务器重启后,会发现第一次的请求响应中,带上了Set-Cookie:cookie1=cookie1; Path=/,但是请求头中并没有出现cookie
de3337d0-f6ff-4bef-88a9-5ed17a75cd92

这时候刷新一下页面,再看看有什么不同?
请求也带上了cookie,也就是说,浏览器已经把cookie记下来了

bae3859a-16ea-4acb-bbab-acddc053820d

多加个cookie试试

app.get('/',(req, res) => {
  res.cookie('cookie1', 'cookie1')
  res.cookie('cookie2', 'cookie2')
  res.cookie('cookie3', 'cookie3')
  res.send('Hello cookie-demo')
});

重启刷新两次页面,再看看?

9e805eae-d49f-445b-b55b-ba98cc60cad1

属性

**expires** : Cookie 失效日期
**max-age**:在 cookie 失效之前需要经过的秒数
**Domain**:指定 cookie 可以送达的主机名。
**Path**:指定一个 URL 路径,这个路径必须出现在要请求的资源的路径中才可以发送 Cookie 首部
**Secure**:一个带有安全属性的 cookie 只有在请求使用SSL和HTTPS协议的时候才会被发送到服务器。
**httpOnly**:设置了 HttpOnly 属性的 cookie 不能使用 JavaScript 经由  Document.cookie 属性、XMLHttpRequest 和  Request APIs 进行访问,以防范跨站脚本攻击(XSS)。
设置属性:expires,max-age, httpOnly
const experss = require('express');
const app = experss();

app.get('/', (req, res) => {
  // 失效时间点
  res.cookie('cookie1', 'cookie1', {
    expires: new Date(Date.now() + 10000)
  });
  // 失效时长
  res.cookie('cookie2', 'cookie2', {
    maxAge: 10000
  });
  // httpOnly
  res.cookie('cookie3', 'cookie3',{
    httpOnly: true
  });
  res.send('Hello cookie-demo');
});

app.listen(3000, () => {
  console.log('Example app listening on port 3000!');
});

e047f74b-bb27-4b6a-989e-88352fa62119

由于设置了httpOnly,所以cookie3读不出来
32d86ed1-289d-4c97-9a50-b190f6e84022

过了十秒钟再刷新,cookie1和cookie2没有了
525133ec-61bf-4ac5-8f54-5717fb3955a9

作用域domain

child1.parent.comchild2.parent.com 是子域,parent.com 是父域。
当 Cookie 的 domain 为child1.parent.com时 ,那么只有访问child1.parent.com的时候就会带上 Cookie,访问child2.parent.com 的时候是不会带上的
当 Cookie 的 domain 为parent.com时,那么访问child1.parent.comchild2.parent.com 都会带上 Cookie

作用路径
app.get('/parent', (req, res) => {
  res.cookie('parent-name', 'parent-value', {
    path: '/parent'
  })
  res.send('<h1>父路径!</h1>')
})

app.get('/parent/childA', (req, res) => {
  res.cookie('child-name-A', 'child-value-A', {
    path: '/parent/childA'
  })
  res.send('<h1>子路径A!</h1>')
})

app.get('/parent/childB', (req, res) => {
  res.cookie('child-name-B', 'child-value-B', {
    path: '/parent/childB'
  })
  res.send('<h1>子路径B!</h1>')
})

efce0479-7511-4d19-a05a-7c83955ce2c2

在子路径内可以访问访问到父路径的 Cookie,反过来就不行
父路径就访问不到子路径的cookie
3680d948-30f6-44a9-90be-0198b938db87

客户端操作cookie

读取

document.cookie

添加

document.cookie='name=value; expires=Thu, 26 Feb 2119 11:50:25 GMT; domain=sankuai.com; path=/';
domain根据需要设置

修改

跟添加是一样的操作,如果name跟现有cookie一样,则改写,否则是添加

删除

把max-age改为0即可

let removeCookie = (name, path, domain) => {
  document.cookie = `${name}=; path=${path}; domain=${domain}; max-age=0`
}