转载cookie理解
本文转自https://www.cnblogs.com/dojo-lzz/p/5580301.html
服务器端像客户端发送Cookie是通过HTTP响应报文实现的,在Set-Cookie
中设置需要像客户端发送的cookie,cookie格式如下:
Set-Cookie: "name=value;domain=.domain.com;path=/;expires=Sat, 11 Jun 2016 11:29:42 GMT;HttpOnly;secure"
其中name=value
是必选项,其它都是可选项。Cookie的主要构成如下:
- name:一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的。
- value:存储在cookie中的字符串值。
最好为cookie的name和value进行url编码
- domain:cookie对于哪个域是有效的。所有向该域发送的请求中都会包含这个cookie信息。这个值可以包含子域(如:yq.aliyun.com),也可以不包含它(如:.aliyun.com,则对于aliyun.com的所有子域都有效).
- path: 表示这个cookie影响到的路径,浏览器跟会根据这项配置,像指定域中匹配的路径发送cookie。
- expires:失效时间,表示cookie何时应该被删除的时间戳(也就是,何时应该停止向服务器发送这个cookie)。如果不设置这个时间戳,浏览器会在页面关闭时即将删除所有cookie;不过也可以自己设置删除时间。这个值是GMT时间格式,
如果客户端和服务器端时间不一致,使用expires就会存在偏差
。 - max-age: 与expires作用相同,用来告诉浏览器此cookie多久过期(单位是秒),而不是一个固定的时间点。正常情况下,max-age的优先级高于expires。
- HttpOnly: 告知浏览器不允许通过脚本
document.cookie
去更改这个值,同样这个值在document.cookie中也不可见。但在http请求张仍然会携带这个cookie。注意这个值虽然在脚本中不可获取,但仍然在浏览器安装目录中以文件形式存在。这项设置通常在服务器端设置。 - secure: 安全标志,指定后,只有在使用SSL链接时候才能发送到服务器,如果是http链接则不会传递该信息。
就算设置了secure 属性也并不代表他人不能看到你机器本地保存的 cookie 信息,所以不要把重要信息放cookie就对了
服务器端设置cookie示例如下:
var http = require('http');
var fs = require('fs');
http.createServer(function(req, res) {
res.setHeader('status', '200 OK');
res.setHeader('Set-Cookie', 'isVisit=true;domain=.yourdomain.com;path=/;max-age=1000');
res.write('Hello World');
res.end();
}).listen(8888);
console.log('running localhost:8888')
直接设置Set-Cookie
过于原始,我们可以对cookie的设置过程做如下封装:
var serilize = function(name, val, options) {
if (!name) {
throw new Error("coolie must have name");
}
var enc = encodeURIComponent;
var parts = [];
val = (val !== null && val !== undefined) ? val.toString() : "";
options = options || {};
parts.push(enc(name) + "=" + enc(val));
// domain中必须包含两个点号
if (options.domain) {
parts.push("domain=" + options.domain);
}
if (options.path) {
parts.push("path=" + options.path);
}
// 如果不设置expires和max-age浏览器会在页面关闭时清空cookie
if (options.expires) {
parts.push("expires=" + options.expires.toGMTString());
}
if (options.maxAge && typeof options.maxAge === "number") {
parts.push("max-age=" + options.maxAge);
}
if (options.httpOnly) {
parts.push("HTTPOnly");
}
if (options.secure) {
parts.push("secure");
}
return parts.join(";");
}
需要注意的是,如果给cookie设置一个过去的时间,浏览器会立即删除该cookie
;此外domain项必须有两个点,因此不能设置为localhost
:
something that wasn't made clear to me here and totally confused me for a while was that domain names must contain at least two dots (.),hence 'localhost' is invalid and the browser will refuse to set the cookie!
服务器端解析cookie
cookie可以设置不同的域与路径,所以对于同一个name value
,在不同域不同路径下是可以重复的,浏览器会按照与当前请求url或页面地址最佳匹配的顺序来排定先后顺序
所以当前端传递到服务器端的cookie有多个重复name value
时,我们只需要最匹配的那个,也就是第一个。服务器端解析代码如下:
var parse = function(cstr) {
if (!cstr) {
return null;
}
var dec = decodeURIComponent;
var cookies = {};
var parts = cstr.split(/\s*;\s*/g);
parts.forEach(function(p){
var pos = p.indexOf('=');
// name 与value存入cookie之前,必须经过编码
var name = pos > -1 ? dec(p.substr(0, pos)) : p;
var val = pos > -1 ? dec(p.substr(pos + 1)) : null;
//只需要拿到最匹配的那个
if (!cookies.hasOwnProperty(name)) {
cookies[name] = val;
}/* else if (!cookies[name] instanceof Array) {
cookies[name] = [cookies[name]].push(val);
} else {
cookies[name].push(val);
}*/
});
return cookies;
}
客户端的存取
浏览器将后台传递过来的cookie进行管理,并且允许开发者在JavaScript中使用document.cookie
来存取cookie。但是这个接口使用起来非常蹩脚。它会因为使用它的方式不同而表现出不同的行为
。
当用来获取属性值时,document.cookie返回当前页面可用的(根据cookie的域、路径、失效时间和安全设置)所有的字符串,字符串的格式如下:
"name1=value1;name2=value2;name3=value3";
当用来设置值的时候,document.cookie属性可设置为一个新的cookie字符串。这个字符串会被解释并添加到现有的cookie集合中。如:
document.cookie = "_fa=aaaffffasdsf;domain=.dojotoolkit.org;path=/"
设置document.cookie并不会覆盖cookie,除非设置的
name value domain path
都与一个已存在cookie重复。
由于cookie的读写非常不方便,我们可以自己封装一些函数来处理cookie,主要是针对cookie的添加、修改、删除。
var cookieUtils = {
get: function(name){
var cookieName=encodeURIComponent(name) + "=";
//只取得最匹配的name,value
var cookieStart = document.cookie.indexOf(cookieName);
var cookieValue = null;
if (cookieStart > -1) {
// 从cookieStart算起
var cookieEnd = document.cookie.indexOf(';', cookieStart);
//从=后面开始
if (cookieEnd > -1) {
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
} else {
cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, document.cookie.length));
}
}
return cookieValue;
},
set: function(name, val, options) {
if (!name) {
throw new Error("coolie must have name");
}
var enc = encodeURIComponent;
var parts = [];
val = (val !== null && val !== undefined) ? val.toString() : "";
options = options || {};
parts.push(enc(name) + "=" + enc(val));
// domain中必须包含两个点号
if (options.domain) {
parts.push("domain=" + options.domain);
}
if (options.path) {
parts.push("path=" + options.path);
}
// 如果不设置expires和max-age浏览器会在页面关闭时清空cookie
if (options.expires) {
parts.push("expires=" + options.expires.toGMTString());
}
if (options.maxAge && typeof options.maxAge === "number") {
parts.push("max-age=" + options.maxAge);
}
if (options.httpOnly) {
parts.push("HTTPOnly");
}
if (options.secure) {
parts.push("secure");
}
document.cookie = parts.join(";");
},
delete: function(name, options) {
options.expires = new Date(0);// 设置为过去日期
this.set(name, null, options);
}
}
转载cookie理解的更多相关文章
- [serverlet][转载: 深入理解HTTP Session]
[serverlet][转载: 深入理解HTTP Session] 标签(空格分隔): 未分类 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任. ...
- cookie理解与实践【实现简单登录以及自动登录功能】
cookie理解 Cookie是由W3C组织提出,最早由netscape社区发展的一种机制 http是无状态协议.当某次连接中数据提交完,连接会关闭,再次访问时,浏览器与服务器需要重新建立新的连接: ...
- [转载]深度理解Session
什么是session session的官方定义是:Session:在计算机中,尤其是在网络应用中,称为“会话控制”.Session 对象存储特定用户会话所需的属性及配置信息. 说白了session就是 ...
- [转载]深入理解HTTP Session
深入理解HTTP Session session在web开发中是一个非常重要的概念,这个概念很抽象,很难定义,也是最让人迷惑的一个名词,也是最多被滥用的名字之一,在不同的场合,session一次的 ...
- [转载] 深入理解Android之Java虚拟机Dalvik
本文转载自: http://blog.csdn.net/innost/article/details/50377905 一.背景 这个选题很大,但并不是一开始就有这么高大上的追求.最初之时,只是源于对 ...
- 转载 深入理解JavaScript中的this关键字
转载原地址: http://www.cnblogs.com/rainman/archive/2009/05/03/1448392.html 深入理解JavaScript中的this关键字 1. 一 ...
- [转载] 快速理解Kafka分布式消息队列框架
转载自http://blog.csdn.net/xiaolang85/article/details/18048631 ==是什么 == 简单的说,Kafka是由Linkedin开发的一个分布式的消息 ...
- Linux安装Tomcat-Nginx-FastDFS-Redis-Solr-集群——【第五集之补充-转载“深入理解VMware虚拟网络”】
郑重声明,此文太好,按耐不住要保存起来好好研究研究,如果侵权,联系我. 转载自王春海的http://blog.51cto.com/wangchunhai/381225,有所更改. 同时可以参考:htt ...
- [转载]深入理解JavaScript系列 --汤姆大叔
深入理解JavaScript系列文章,包括了原创,翻译,转载,整理等各类型文章,如果对你有用,请推荐支持一把,给大叔写作的动力. 深入理解JavaScript系列(1):编写高质量JavaScript ...
随机推荐
- vss安装注意点
一:装好IIS 二:win7用管理员权限打开 server configuration 才能打上勾 三:用计算机名,不要用 Ip地址
- 使用docker+tomcat部署jenkins
- BZOJ 5299: [Cqoi2018]解锁屏幕
状压DP #include<cstdio> using namespace std; const int mod=1e8+7; int F[1000005][25],dis[25][25] ...
- luogu1169 [ZJOI2007]棋盘制作
悬线法 #include <iostream> #include <cstring> #include <cstdio> using namespace std; ...
- day05_04 数据类型-数值、布尔值、字符串简介
数据运算 数据类型初识 数字 整数 int(integer) 整型 长整型 在python3里面已经不区分整型和长整型了,统一都叫整型 在32位机器上,整数的位数为32位,取值范围为-2**31-2* ...
- day01_13.数组
数组基本语法 <?php $a = array(键1=>值1,键2=>值2); ?> <?php $arr = array(1=>'张三的裤子',2=>'李四 ...
- Python封装与隐藏
今日内容: 1.封装与隐藏2.property3.绑定方法与非绑定方法 知识点一:封装与隐藏 1.什么封装: 封:属性对外是隐藏的,但对内是开放的 装:申请一个名称空间,往里装入一系列名字 ...
- django demo --blog
详情,请看虫师博客http://www.cnblogs.com/fnng/p/3737964.html 和https://my.oschina.net/matrixchan/blog/184445 ...
- hihoCoder #1343 Stable Members
题目大意$\newcommand{\SD}{\mathrm{SD}}$ 给定一个 $n+1$ 个点的有向无环图,点从 $0$ 开始编号.无重边.自环,且从每个点 $u$ 都能到达 $0$ 号点.如果每 ...
- no main manifest attribute, in demo-1.0.jar
今天想打包一个jar到Linux上运行,发现使用java -jar demo-1.0.jar 运行报错: no main manifest attribute, in demo-1.0.jar 解决方 ...