Cookie的操作
什么是cookie
cookie的由来
在客户端和服务端通信的过程中,服务端如果需要记录客户端的信息,就要设计一类文件来实现存储。服务端存储用户信息的东西就是session,用户在某个站点留下的信息可以存储在服务器中。但是单单只用session还不够,因为这样会服务器需要存储大量的用户信息,压力会很大,所以cookie就应运而生了。
cookie和session经常在网上被大家放在一起讨论,原因在于它和session的目的都是存储记录用户的信息的,但是除此之外,二者在其他方面是几乎完全不一样的。至于二者的机制有何区别,可以参考这篇博文:Cookie 与 Session 的区别
简要概括一下session和cookie的区别:
cookie存储在客户端,session存储在服务端;
cookie可以用来跟踪会话,也可以保存用户名和密码;session用来跟踪会话
cookie的基本属性
在控制台中,我们可以在application选项中查看到网站的cookie,cookie的属性也显示在其中,包括了 Name、value、Domain、path、Expires/Max-Age、Size、HTTP、Secure等等
- Name: cookie名称,创建后无法改动
- value:cookie值,若为Unicode字符,则需要字符编码;若为二进制数据,则需要base64编码
- domain:可以访问该cookie的域名。非顶级域名cookie的domain只能是顶级域名或者自身域名,且无法读取其他非顶级域名的cookie(?),顶级域名cookie的domain只能是顶级域名
- path:可以访问该cookie的路径
- expires/max-age:保持有效的时间,单位为秒,若为负数,关闭浏览器即消失。expires已经过时,尽管今天的浏览器仍然支持它。请改用max-age变量,因为它更容易使用。注意不要使用“expires”作为变量名来存储数据。
- http:httponly,若为true,则只有在http请求头中会带有该cookie的信息,无法通过document.cookie访问
- secure:是否用https传递cookie
一般的,一个浏览器针对一个网站最多存20个cookie,浏览器总共只允许存放300个cookie。每个cookie的长度不能超过4K。
cookie是以键值对形式保存的,各个cookie之间一般以分号隔开,比如这样:
theme=blue; max-age=60; path=/; domain=baidu.com
补充:如果没有设置有效时间,那么cookie是保存在计算机内存的,浏览器关闭即删;若设置了有效时间,那么就会保存到硬盘
关于安全性
常见的攻击方式
防范
用户可以设置HttpOnly和secure属性来抵御攻击。设置了HttpOnly属性后,就可以防御脚本读取cookie信息(XSS); 设置了secure=true,cookie只能在https连接中被浏览器传递到服务端
cookie加密也是一个基本操作
cookie安全的话题可以参考:单点登录与权限管理本质:cookie安全问题
cookie的具体操作
网上看到的一个简易封装的代码
var cookieUtil = {
setCookie: function(name, value, expiresDays) {
var date = new Date();
date.setDate(date.getDate() + expiresDays);
document.cookie = name + "=" + escape(value) + ";" + ((expiresDays == null) ? "" : ";expires=" + date.toGMTString());
},
getCookie: function(name) {
var cookies = document.cookie;
var start = cookies.indexOf(name + "=");
if (start === -1) {
return "";
}
start = start + name.length + 1;
var end = cookies.indexOf(";", start);
//是最后一个键值对(末尾没有分号)
if (end === -1) {
end = document.cookie.length;
}
return unescape(document.cookie.substring(start, end));
},
deleteCookie: function(name) {
//将过期日期设置为前一天
this.setCookie(name, "", -1);
}
}
设置cookie
设置cookie比较简单,只需将cookie所需的字符串分配给document.cookie属性即可。
document.cookie = "theme=" + encodeURIComponent("blue theme") + "; max-age=" + 60*60*24 + "; path=/; domain=baidu.com";
封装成一个函数:
function setCookie(cookieName, cookieValue, days, domain) {
var domainString = domain ? ("; domain=" + domain) : '';
document.cookie = cookieName + "=" + encodeURIComponent(cookieValue) + "; max-age=" + 60*60*24*days + "; path=/" + domainString;
}
//调用
setCookie("colortheme", "theme", 2, "baidu.com")
或者
//from : https://www.sitepoint.com/how-to-deal-with-cookies-in-javascript/
function createCookie(name, value, expires, path, domain) {
var cookie = name + "=" + escape(value) + ";";
if (expires) {
// If it's a date
if(expires instanceof Date) {
// If it isn't a valid date
if (isNaN(expires.getTime()))
expires = new Date();
}
else
expires = new Date(new Date().getTime() + parseInt(expires) * 1000 * 60 * 60 * 24);
cookie += "expires=" + expires.toGMTString() + ";";
}
if (path)
cookie += "path=" + path + ";";
if (domain)
cookie += "domain=" + domain + ";";
document.cookie = cookie;
}
// Usage
createCookie("website", "audero.it", new Date(new Date().getTime() + 10000));
createCookie("author", "aurelio", 30);
读取cookie
// 1
function getCookie(cookieName) {
var cookieName = encodeURIComponent(cookieName) + "=",
cookieStart = document.cookie.indexOf(cookieName),
cookieValue = null;
if (cookieStart > 1) {
var cookieEnd = document.cookie.indexOf(";", cookieStart);
if (cookieEnd === -1) {
cookieEnd = document.cookie.length;
}
cookieValue = decodeURIComponent(document.cookir.substring(cookieStart + document.cookie.length, cookieEnd))
}
return cookieValue;
}
// 2
function getCookie(cookieName) {
var cookieString = document.cookie;
if (cookieString.length !== 0) {
var cookieArray = cookieString.split('; ');
for (var i = 0; i < cookieArray.length; i++) {
var cookieValue = cookieArray[i].match(cookieName + '=(.*)');
if (cookieValue) {
return decodeURIComponent(cookieValue[1]);
}
}
}
return '';
}
删除cookie
有时您可能想要删除Cookie,例如访问者退出您的网站时。为此,可以将max-age变量设置为相同路径和域中相同cookie的0(零)或者是负数:
function deleteCookie(cookieName, domain) {
var domainString = domain ? ("; domain=" + domain) : '';
document.cookie = cookieName + "=; max-age=0; path=/" + domainString;
}
修改cookie
可以新建一个同名的cookie覆盖原有的cookie
扩展
cookie操作的第三方库:
js-cookie
cookie-encryption