Cookie和Session在Node.JS中的实践(一)
Cookie和Session是一个非常有趣的概念,也是一个老生常谈的话题。然而,作者看了许多文章,也翻看了几本书籍,它们对Cookie和Session的概念、机制的描述都各不一致,大多文章都只谈到了Cookie和Session其中之一,但在现实开发中两者都需要使用。作者有时候写程序用到了两者但有时候连自己都没理解他们之间的区别、联系、机制等等概念。

Cookie
HTTP的无状态协议是产生Cookie技术的重要原因
HTTP是一种不保存状态,即无状态(stateless)协议。HTTP协议自身不对请求和响应之间的通信转台进行保存。也就是说HTTP是不会做持久化(Persistence)处理的。当使用HTTP进行通信时,每当有新的请求发送,就会有对应的新响应产生。这并不是缺陷,而是HTTP为了更快的处理大量事务。

然而,无状态协议让业务处理变得困难的情况越来越多了,如:我们登录了某宝,就算我们跳转到了某宝的其他页面,也需要保持登录这个“状态”,但HTTP协议做不到。针对这个例子,网站为了掌握是谁发送的请求,就需要把用户的状态保存起来。
为了实现期望的保持状态功能,于是引入了Cookie技术,所以cookie的主要作用就是记录状态,包括会话状态管理,用户的个性化设置,浏览器的行为跟踪。有了Cookie再用HTTP通信就可以管理状态,因此就有人说Cookie是HTTP的扩展。
客户端中的Cookie
Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。
这是我们经常听到的关于Cookie的概念,但从来没见过Cookie长什么样子。在Chrome中通过开发者工具可以查看网站用到的所有Cookie,以博客园用到的Cookie为例。

另外我们可以使用JavaScript原生的API获取cookie:document.cookie,使用该方法获只能获取非HttpOnly类型的cookie。

跟直接在chrome查看cookie,使用控制台Console得到的结果除了HttpOnly以外的Cookie都是一样的。可以发现,每一个cookie都有几个不同的字段:name,value,domain,path,expires/max-age,HttpOnly,secure来分析一下比较常用的字段:
name和value
设置cookie的名字和值。必须设置字段。
domain和path
domain是域名,path是路径,两者加起来就是URL,domain结合path一起来限制cookie能被哪些URL访问。概念比较抽象,举个例子
以博客园为例,博客园cookie的
domain为"cnblogs.com",path为"/",若我们请求的URL的域名是"cnblogs.com"或者它的子域"home.cnblogs.com",并且URL的路径都是"/"或者它的子路径"/example","/home/user",以上这些URL都能访问cookie,浏览器会将这些cookie添加到请求的cookie头部中去。
以上两个字段是可选的,domain默认cookie所在的域名,path默认设置该cookie的网页所在的目录。
secure
带有此字段的cookie表示只有在请求使用HTTPS协议的时候才能被传到服务器中。但通常建议不会把保密的数据放到cookie中存储。
HttpOnly
JavaScript原生API能访问浏览器的cookie,这可能会遭遇XSS攻击,为了防范,设置了该字段的cookie,原生API是无法访问的。
expire和Max-age
expires:表示cookie的最长有效时间,cookie失效时刻=expires形式是符合HTTP-date规范的时间戳,这个Date是一个通用的首部,语法:Date: <day-name> <day> <month> <year> <hour>:<minute>:<second> GMT,可以通过new Date().toGMTString获得。
Max-Age:表示cookie存储的最长时间。单位是秒,有效期:创建时刻+max-age。跟expire的作用的一样的,若两者都存在则Max-Age的优先级高。该属性在一些老浏览器中不支持。
如果没有给cookie设置以上这两个字段,那么cookie默认就是所谓的会话Cookie,有效期就是session,这里的session指的就是会话,浏览器关闭后cookie就没有了整个过程就是一个会话。
HTTP+COOKIE工作原理
HTTP是无状态协议,所以需要COOKIE技术来保持状态。我们知道,Cookie是服务器发送到用户浏览器并保存在本地的一小块数据,这里分析一下HTTP+COOKIE的工作原理:
考虑两种可能:
1.客户端第一请求该台服务器,也就是服务器没有发送cookie给该台客户端,因此客户端的第一次请求是没有cookie首部字段数据的,而服务器作为响应也会将cookie首部数据发送到该台客户端中。

2.客户端不是第一次请求该台服务器,服务器已经有发送过cookie给该台客户端,那么在客户端上的cookie都会随着请求一同发送到服务器中,而服务器会检查这个cookie给你返回相应的数据,而不再需要设定cookie。

COOKIE实践
为了能明白上面的cookie工作原理,以下进行实践,建议读者跟我一起做
1.还是以博客园为例,在账户退出的状态下打开(https://www.cnblogs.com)[博客园首页],使用Chrome,如果对浏览器开发工具比较熟悉也可以使用火狐,把网站以往的cookie清除

2.进行刷新页面,再打开chrome开发工具network,选择其中的请求,点击查看请求首部(Request Header)以及响应首部(Response Header),发现响应首部有set-cookie字段,即服务器给浏览器设置的cookie。并且,请求首部是没有cookie字段的,因为我们自己清除了cookie!


此时,再去查看Cookie面板发现服务器已经给浏览器设置了Cookie。
再次刷新页面。自行重复以上步骤,发现请求首部多了一个cookie字段,即有了cookie后,对服务器的每一次请求都会带上cookie。

总结
HTTP的无状态协议是产生Cookie技术的重要原因,cookie是服务器发送到用户浏览器并保存在本地的一小块数据,它会在浏览器下次向同一服务器再发起请求时被携带并发送到服务器上。cookie的主要作用就是记录状态,包括会话状态管理,用户的个性化设置,浏览器的行为跟踪。
写到这,已经涉及不少知识,文章篇幅太长不好,第二篇再写session以及在node.JS的实践。剧透一下,通过Node.JS操作cookie的代码:)
const express = require('express');
const cookieParser = require('cookie-parser')
var server = express();
server.use(cookieParser('alkdukajvldfq'));
server.use('/', function(req, res) {
// 发送cookie,path是指定能访问cookie的路径,可从下往上读取,反则不行,比如/=>path:/aaa
res.cookie('name', 'janro', {path: '/', maxAge: 3600*1000, signed: true});
// 读取cookie
console.log(req.cookies);
console.log(req.signedCookies);
// / 和favicon
console.log(req.url);
res.send('OK');
//清除cookie
res.clearCookie('name');
});
server.listen(8080);
下次,session见。
如果您觉得阅读本文对您有帮助,请点一下“推荐”按钮,您的“推荐”将是我最大的写作动力!
Reference
- https://segmentfault.com/a/1190000004556040
- https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
- https://segmentfault.com/a/1190000007579928
- 图解HTTP
- JavaScript高级程序设计
Cookie和Session在Node.JS中的实践(一)的更多相关文章
- Cookie和Session在Node.JS中的实践(三)
Cookie和Session在Node.JS中的实践(三) 前面作者写的COOKIE篇.SESSION篇,算是已经比较详细的说明了两者间的区别.机制.联系了.阅读时间可能稍长,因为作者本身作图也做了不 ...
- Cookie和Session在Node.JS中的实践(二)
Cookie和Session在Node.JS中的实践(二) cookie篇在作者的上一篇文章Cookie和Session在Node.JS中的实践(一)已经是写得算是比较详细了,有兴趣可以翻看,这篇是s ...
- Node.js中的Session,不要觉得简单哦。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...
- 在node.js中使用COOKIE
node.js中如何向客户端发送COOKIE呢?有如下两个方案: 一.使用response.writeHead,代码示例: //设置过期时间为一分钟 var today = new Date(); v ...
- Node.js中的不安全跳转如何防御详解
Node.js中的不安全跳转如何防御详解 导语: 早年在浏览器大战期间,有远见的Chrome认为要运行现代Web应用,浏览器必须有一个性能非常强劲的Java引擎,于是Google自己开发了一个高性能的 ...
- 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查
Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...
- 如何在Node.js中合并两个复杂对象
通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...
- Node.js 中MongoDB的基本接口操作
Node.js 中MongoDB的基本接口操作 连接数据库 安装mongodb模块 导入mongodb模块 调用connect方法 文档的增删改查操作 插入文档 方法: db.collection(& ...
- 初步揭秘node.js中的事件
当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...
随机推荐
- 一个画ROC曲线的封装包
Draw_ROC_Curves This is a python file which is used for drawing ROC curves -f : assign file name -t ...
- ERC720和erc721的区别
有一阵子,Ethereum网络突然变的特别拥堵,原因是兴起了一款以太坊养猫的Dapp游戏,超级可爱的猫形象,再加上配种,繁殖和拍卖等丰富的玩法,风靡了币圈. 一时间币圈大大小小的人都在撸猫,以太坊网络 ...
- HDU 4669 Mutiples on a circle 动态规划
参考了官方题解给的方法: 对于处理循环,官方给了一种很巧妙的方法: #include <cstdio> #include <cstring> #include <cstd ...
- 安卓context(一)
最近看了一下深入安卓内核,毫无安卓基础的我一头深入不可自拔,看的是云里雾里,第一遍看到一半左右似乎开始失去了效率. 现在开始第二遍,并对看过的重要知识点以个人的理解进行梳理(不免有错的地方,好心人请告 ...
- Oracle常用数据库系统表单以及SQL的整理
因为最近涉及到了一些数据库的归档,备份等工作,所以一部分的重心放在了数据库上,毕竟之前对数据库的了解也只停留在了一般的建表,查询,最多最多再写一写触发器之类的东西. 通常都是自己瞎搞搞,也就懂一点皮毛 ...
- android ListView与EditText共存错位
在一个ListView中,如果里面有EditText会很麻烦,因为修改EditText里面的数据会发生错位现象. 这时候,需要在适配器BaseAdapter的getView中设置setTag(),将p ...
- 想了一天的题目QAQ 毛线数列的最值
#include <cstdio> #include <cstring> #include <cmath> #include <iostream> #i ...
- 测试计划驱动开发模式 TPDD:一种比 TDD 更友好的开发模式
相信大部分开发团队都在使用TDD,并且还有很多开发团队都 对外声明 在使用 TDD 开发模式. 之所以说是“对外声明”,是因为很多开发团队虽然号称使用的是 TDD 开发模式,实际开发过程中却无法满足 ...
- 自适应注意力机制在Image Caption中的应用
在碎片化阅读充斥眼球的时代,越来越少的人会去关注每篇论文背后的探索和思考. 在这个栏目里,你会快速 get 每篇精选论文的亮点和痛点,时刻紧跟 AI 前沿成果. 点击本文底部的「阅读原文」即刻加入社区 ...
- 7月9日day1总结
今天的学习过程和小结 上午学习了前端包括html,CSS,js等基本内容 前端10.25.134.187 html js css 1.块元素 ---默认占满整行,如果设置了高度和宽度都有效,如果不设置 ...