-
Notifications
You must be signed in to change notification settings - Fork 184
Description
看了很多关于cookie与session的理论文章,项目中日常也经常用,但自己是前端er,对后端一直抱有好奇心,这次就拿cookie开到,跑一个全流程吧,也顺便作为巩固cookie知识的一个实践
搭建服务器,初始化
通过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即可看到如下界面
还可以看到,页面已经有了一个请求,但没有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
这时候刷新一下页面,再看看有什么不同?
请求也带上了cookie,也就是说,浏览器已经把cookie记下来了
多加个cookie试试
app.get('/',(req, res) => {
res.cookie('cookie1', 'cookie1')
res.cookie('cookie2', 'cookie2')
res.cookie('cookie3', 'cookie3')
res.send('Hello cookie-demo')
});
重启刷新两次页面,再看看?
属性
**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!');
});
作用域domain
child1.parent.com 和child2.parent.com 是子域,parent.com 是父域。
当 Cookie 的 domain 为child1.parent.com时 ,那么只有访问child1.parent.com的时候就会带上 Cookie,访问child2.parent.com 的时候是不会带上的
当 Cookie 的 domain 为parent.com时,那么访问child1.parent.com和child2.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>')
})
在子路径内可以访问访问到父路径的 Cookie,反过来就不行
父路径就访问不到子路径的cookie
客户端操作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`
}