HTML5学习笔记(二十九):Cookie和Session
HTTP协议本身是无状态的,这和HTTP最初的设计是相符的,每次请求都是创建一个短连接,发送请求,得到数据后就关闭连接。即每次连接都是独立的一次连接。
这样的话,导致的问题就是当我在一个页面登陆了账号之后,点击连接打开的新界面或者关闭后再打开我都需要再次登陆账号,所以我们需要借助Cookie和Session来记录网页的状态。
Cookie
Cookie,有时也用其复数形式 Cookies。可以简单的理解为存储在浏览器的文本数据。
Cookie按域名来进行存储,不同的域名存储的Cookie相互之间不能访问时隔绝的。而在当前域名存在Cookie时,每次向服务端进行请求时都会在HTTP请求头中,把当前域名下的所有Cookie都一起进行提交。这样服务端就可以获取当前网站存储的所有Cookie数据。而服务端在进行返回时也可以在HTTP响应头中附带上新的Cookie,浏览器接收到返回时,会保存服务端发送的Cookie,这样下次请求,服务端又可以获得新发送的Cookie数据。
下面我们来详细的看看Cookie的一些特性。
不可跨域名
根据Cookie的规范,这是由Cookie的隐私安全机制决定的。隐私安全机制能够禁止网站非法获取其他网站的Cookie。不同域名的网站下面的Cookie是互相不能访问的,你当前在cnblog下,就不能获取和操作的baidu的Cookie,这是比较好理解的。
域名
正常情况下,同一个一级域名下的两个二级域名如www.baidu.com和images.baidu.com也不能交互使用Cookie,因为二者的域名并不严格相同。
如果想所有baidu.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数为.baidu.com。这样所有二级三级域名,都可以访问这个Cookie。
注意:domain参数必须以点(".")开始。
路径
domain属性决定运行访问Cookie的域名,而path属性决定允许访问Cookie的路径。
例如,如果只允许/session/下的程序使用Cookie,可以设定path参数为/session/。
设置为“/”时允许所有路径使用Cookie。path属性需要使用符号“/”结尾。
注意:页面只能获取它属于的Path的Cookie。例如/session/test/a.jsp不能获取到路径为/session/abc/的Cookie。使用时一定要注意。
有效期
Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。
如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。
如果maxAge为负数,则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文件中。
如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除。
Cookie默认的maxAge值为–1。
安全属性
HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。
提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。
存储中文和图片
中文需要使用escape和unescape两个方法进行编码和解码,否则会出现乱码。
图片可以使用Base64编码为字符串来保存。
浏览器发送cookie规则
在发起一个请求时,浏览器会选择什么样的Cookie数据传递到服务端呢?
根据请求url中的域名在cookie列表中找所有与当前域名一样的cookie,然后再根据指定的路径进行匹配,如果当前请求在域匹配的基础上还与路径匹配那么就会将所有匹配的cookie发送给服务器。
也可以手动指定cookie的适用的域(domain),然后手动指定路径(path)。
一些需要注意的地方
- 可能会被用户禁用:Cookie是保存在浏览器端的,所以用户有权利选择关闭Cookie。
- 存储大小有限制:不同的浏览器都对Cookie的存储大小有限制,Cookie不宜存储过多的数据。
- 容易被删除:用户可以随时清空Cookie。
- 安全性不够高:Cookie是用明文的方式存储的,不适合保存敏感的数据。
Session
在Web端保存用户状态的方式除了Cookie外,还可以使用Session来进行保存,不同的是Cookie保存在浏览器,而Session保存在服务端。
Session的存取都只能在服务端进行操作,所以浏览器是不能直接对Session的数据进行读取和操作的(间接当然是可以的,浏览器可以发送数据给服务端用来存Session的值,服务端也可以直接把Session的值作为返回值返回到浏览器)。
唯一要解决的问题就是,因为每次请求都是独立的,所以服务端需要知道每次的请求的身份,比如我和李雷同时请求,服务端需要知道那些请求是我的,那些是李雷的。
解决这个问题的方式一般如下:当服务端开始使用Session时,会生成一个guid用来标记本次请求的客户端,可以把这个guid看做是这个客户端的id,然后,会把这个guid作为Cookie发送给浏览器。浏览器会自动保存这个guid,下次客户端再次请求时,这个Cookie会传递给服务端,服务端得到guid后,就可以获取之前的Session的所有数据了。
示例
下面我们以NodeJS的Express框架为例,来看一下Session的例子。
我们第一次请求时,浏览器的请求头没有包含任何的Cookie信息,但是服务端的响应头里包含了一个名为connect.sid的Cookie信息返回到浏览器,这个connect.sid就是服务端生成的SessionID。

后续的请求,浏览器的请求头中就会包含名为connect.sid的SessionID,服务端可以知道当前请求的SessionID,就可以获取前面请求保存的数据了,由于浏览器已经有了SessionID,那么本次的服务端响应头的Cookie就没有再发送connect.sid到浏览器了。

有效期
Session在设定时,都有一个有效时间(这个时间一般都可以配置,不同的语言框架配置方式各异),实际上就是传递到浏览器的Cookie的有效时间,由于Session一般存放在服务端的内存中,如果不清除则会导致内存占用越来越多,最终整个服务器奔溃。所以服务端会在一定的时间清除过期或者长时间不使用的Session及数据。
URL地址重写
由于Cookie可以被人为的禁止,必须有其他机制以便在Cookie被禁止时仍然能够把SessionID传递回服务器。经常被使用的一种技术叫做URL重写,就是把SessionID直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx;sessionid=ByOK ... 99zWpBng!-145788764,另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?sessionid=ByOK ... 99zWpBng!-145788764
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把SessionID的信息和正常程序参数区分开来。
HTML5学习笔记(二十九):Cookie和Session的更多相关文章
- HTML5学习笔记(十九):Lambda和Promise
Lambda 在ES6的标准中称为Arrow Function(箭头函数).下面是一个简单的箭头函数: x => x * x 上面的定义和下面的代码定义效果一样: function (x) { ...
- Java学习笔记二十九:一个Java面向对象的小练习
一个Java面向对象的小练习 一:项目需求与解决思路: 学习了这么长时间的面向对象,我们只是对面向对象有了一个简单的认识,我们现在来做一个小练习,这个例子可以使大家更好的掌握面向对象的特性: 1.人类 ...
- angular学习笔记(二十九)-$q服务
angular中的$q是用来处理异步的(主要当然是http交互啦~). $q采用的是promise式的异步编程.什么是promise异步编程呢? 异步编程最重要的核心就是回调,因为有回调函数,所以才构 ...
- PHP学习笔记二十九【接口】
<?php //定义接口 //接口可以定义属性,但必须是常量而且是public //接口的所有方法必须是public interface Iusb{ public function start( ...
- python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码
python3.4学习笔记(二十六) Python 输出json到文件,让json.dumps输出中文 实例代码 python的json.dumps方法默认会输出成这种格式"\u535a\u ...
- python3.4学习笔记(二十五) Python 调用mysql redis实例代码
python3.4学习笔记(二十五) Python 调用mysql redis实例代码 #coding: utf-8 __author__ = 'zdz8207' #python2.7 import ...
- python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法
python3.4学习笔记(二十四) Python pycharm window安装redis MySQL-python相关方法window安装redis,下载Redis的压缩包https://git ...
- python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字
python3.4学习笔记(二十二) python 在字符串里面插入指定分割符,将list中的字符转为数字在字符串里面插入指定分割符的方法,先把字符串变成list然后用join方法变成字符串str=' ...
- python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法
python3.4学习笔记(二十) python strip()函数 去空格\n\r\t函数的用法 在Python中字符串处理函数里有三个去空格(包括'\n', '\r', '\t', ' ')的函数 ...
- 【转】 Pro Android学习笔记(十九):用户界面和控制(7):ListView
目录(?)[-] 点击List的item触发 添加其他控件以及获取item数据 ListView控件以垂直布局方式显示子view.系统的android.app.ListActivity已经实现了一个只 ...
随机推荐
- SpringBoot使用Mybatis-Generator
本文介绍如何将Maven和Mybatis-Generator配合使用. 简介 Mybatis-Generator是Mybatis提供的一个便捷型插件,自动可以为项目生产对应的实体类,Mapper,da ...
- SpringBoot启动banner更改
这篇文章的开始先给大家看一个图片 用过或者看过springboot的人都知道,这就是springboot启动的banner,这一篇介绍如何自定义springboot的启动bannner. 先介绍一个可 ...
- Alpha(2/10)
鐵鍋燉腯鱻 项目:小鱼记账 团队成员 项目燃尽图 冲刺情况描述 站立式会议照片 各成员情况 团队成员 学号 姓名 git地址 博客地址 031602240 许郁杨 (组长) https://githu ...
- 编辑datagridview单元格
以这3种为例,最简单的是第三种,直接让单元格处于可编辑状态,当完成编辑后触发CellEndEdit事件,最后对输入的数据进行处理. private DateTimePicker dtp = new D ...
- BZOJ.4182.Shopping(点分治/dsu on tree 树形依赖背包 多重背包 单调队列)
BZOJ 题目的限制即:给定一棵树,只能任选一个连通块然后做背包,且每个点上的物品至少取一个.求花费为\(m\)时最大价值. 令\(f[i][j]\)表示在点\(i\),已用体积为\(j\)的最大价值 ...
- 2189 ACM 母函数 素数
题目:http://acm.hdu.edu.cn/showproblem.php?pid=2189 思路:先找出150以内的 素数,然后再用母函数或01背包计算 复习母函数的代码:https://ww ...
- JDK 1.8 新特性
default 函数式接口 待总结
- Markdown 的离线编辑工具推荐:Sublime Text3 or Typora?我推荐Typora
最新版Sublime Text3 通过插件的方式,可以完美支持Markdown文档的编写,但是,唯一不完美的是实时预览的缺陷.可能各位看官要喷了,谁说Sublime Text3 不能实时预览的?你看: ...
- JVM 内存分配模型概念和java中各种对象的存储
JVM 内存分配模型概念 --在工作中可能用到的机会不多,有个概念的了解 --此文是转载某位读者,应该是在阅读了<深入理解Java虚拟机JVM高级特性与最佳实践> 一书后,总结所得.写的不 ...
- ZOJ3967 : Card Game
比赛的时候因为卡内存,在抠内存的时候改错了,导致赛内没有AC,赛后发现数组开的很小都可以AC. 分析题意我们发现,这题需要求出所有存在的直线形成的上凸壳,那么查询$[L,R]$时在凸壳上二分导数,找到 ...