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

  1. https://segmentfault.com/a/1190000004556040
  2. https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Cookies
  3. https://segmentfault.com/a/1190000007579928
  4. 图解HTTP
  5. JavaScript高级程序设计

Cookie和Session在Node.JS中的实践(一)的更多相关文章

  1. Cookie和Session在Node.JS中的实践(三)

    Cookie和Session在Node.JS中的实践(三) 前面作者写的COOKIE篇.SESSION篇,算是已经比较详细的说明了两者间的区别.机制.联系了.阅读时间可能稍长,因为作者本身作图也做了不 ...

  2. Cookie和Session在Node.JS中的实践(二)

    Cookie和Session在Node.JS中的实践(二) cookie篇在作者的上一篇文章Cookie和Session在Node.JS中的实践(一)已经是写得算是比较详细了,有兴趣可以翻看,这篇是s ...

  3. Node.js中的Session,不要觉得简单哦。

    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,博客地址为http://www.cnblogs.com/jasonnode/ .学习网站上有对应 ...

  4. 在node.js中使用COOKIE

    node.js中如何向客户端发送COOKIE呢?有如下两个方案: 一.使用response.writeHead,代码示例: //设置过期时间为一分钟 var today = new Date(); v ...

  5. Node.js中的不安全跳转如何防御详解

    Node.js中的不安全跳转如何防御详解 导语: 早年在浏览器大战期间,有远见的Chrome认为要运行现代Web应用,浏览器必须有一个性能非常强劲的Java引擎,于是Google自己开发了一个高性能的 ...

  6. 在node.js中,使用基于ORM架构的Sequelize,操作mysql数据库之增删改查

    Sequelize是一个基于promise的关系型数据库ORM框架,这个库完全采用JavaScript开发并且能够用在Node.JS环境中,易于使用,支持多SQL方言(dialect),.它当前支持M ...

  7. 如何在Node.js中合并两个复杂对象

    通常情况下,在Node.js中我们可以通过underscore的extend或者lodash的merge来合并两个对象,但是对于像下面这种复杂的对象,要如何来应对呢? 例如我有以下两个object: ...

  8. Node.js 中MongoDB的基本接口操作

    Node.js 中MongoDB的基本接口操作 连接数据库 安装mongodb模块 导入mongodb模块 调用connect方法 文档的增删改查操作 插入文档 方法: db.collection(& ...

  9. 初步揭秘node.js中的事件

    当你学习node.js的时候,Events是一个非常重要的需要理解的事情.非常多的Node对象触发事件,你能在文档API中找到很多例子.但是关于如何写自己的事件和监听,你可能还不太清楚.如果你不了解, ...

随机推荐

  1. [转载]Network-Emulator Network-Emulato

    Network-Emulator-Toolkit网络模拟器使用详细介绍 by:授客 QQ:1033553122 原理介绍 图1 如上图,一个ADSL用户通过modem连接到网络,通过网络应用如IE,M ...

  2. Python全栈工程师(递归函数、闭包)

    ParisGabriel            每天坚持手写  一天一篇  决定坚持几年 全栈工程师     Python人工智能从入门到精通 函数式编程: 是指用一系列函数解决问题 每一个函数完成细 ...

  3. DB2数据库的日志文件管理

    DB2数据库的日志文件管理 DB2的日志模式 1.1循环日志 当循环日志生效时,事务数据将通过循环的方式写入主要日志文件.当存储于某个日志文件中的所有记录都不再需要用于恢复时,该日志文件将被重用,并且 ...

  4. SpringBoot Rabbitmq接收消息

    官网地址:https://docs.spring.io/spring-boot/docs/2.1.3.RELEASE/reference/htmlsingle/#boot-features-amqp ...

  5. Servlet中文件上传

    利用getReader()和getInputstream()上传 package control; import javax.servlet.ServletException; import java ...

  6. ocrosoft Contest1316 - 信奥编程之路~~~~~第三关 问题 M: 当总统

    http://acm.ocrosoft.com/problem.php?cid=1316&pid=12 题目描述 小明想当丑国的总统,丑国大选是按各州的投票结果来确定最终的结果的,如果得到超过 ...

  7. Json对象转json数组

    var arr = [];             arr.push(strData);

  8. 华为手机怎么安装Google

    华为手机怎么安装google 新买了个华为荣耀九,结果安装Google Play提示gms core 步骤一 gms 安装器.应用市场已经下架了  地址:链接: 点击打开链接 密码: m63j 步骤二 ...

  9. 【转】oracle 删除重复记录

    转至:http://blog.163.com/aner_rui/blog/static/12131232820105901451809/ 2.保留一条(这个应该是大多数人所需要的 ^_^) Delet ...

  10. jQuery UI-Draggable 参数集合

    ·概述    在任何DOM元素启用拖动功能.通过单击鼠标并拖动对象在窗口内的任何地方移动.    官方示例地址:http://jqueryui.com/demos/draggable/      所有 ...