返回顶部

javascript中cookie那些事(带实战测试效果)

来源:建枫 发布时间:2016-05-15

前话

其实之前一直对cookie疏于理解,所以对它的概念停留在:cookie是一种在浏览器客户端保存数据的结构!至于它的怎么保存的确实完全不懂,直到最近看了一些文档,才大概理解它的工作模式,所以这边文章记录一下我对cookie的理解,当然了,为了弄懂cookie,有些概念我可能说的“很直接”,缺乏术语专业性,不过只要能帮助我们cookie,我觉得是没有关系的!时间仓促,难免有理解错误的地方,大家包涵!文章会包涵大量实际代码以及测试效果截图,文章中的代码也可以复制直接测试!

基础介绍

直接一点,我们现在脚本中写出如下代码,感受一下cookie吧!

document.cookie = "name=xiaoming";
document.cookie = "password=111111";
document.cookie = "favourateColor=red";

好了,我们赶紧打开浏览器,看看下控制台发生了什么!下面是实际效果截图!(左边是代码,右边是控制台截图)

点击我可产看全图

我们发现,在浏览器控制台,cookie那里存入了类似key-value结构的数据,然后key刚好是我们写的字符串等号左边的字符,而value是等号右边的值;然后我们对document.cookie做了多少条赋值语句,就有个多少个这样的键-值数据。此时当我们在控制台中打印document.cookie时,会得到下面的结果!

点击我可产看全图

我们发现打印document.cookie得到的是上面的键值对拼接得到的一个字符串!这个字符串,后期我们进行的一系列跟用户有关的操作都是利用这个字符串展开的,所以它有重要用途,这点我们先暂把把它放在一边。

由此,我们对cookie做这样的一个定义:我们每次通过对document.cookie赋值一条带有等号的字符串,那么,cookie将按等号左边为键,等号右边为键值,最后以键值对的形式把数据存储在用户的客户端中。有多少条这样的赋值语句,就有多少个键值对!最后我们打印document.cookie将得到的是这些键值对拼接的一个字符串结果,也就是我们最后的得到的(所谓的cookie)是一个字符串!你可以理解这是浏览器内部实现的一个过程!

当然了,我们在给document.cookie赋值的时候,可以设置某个数据的过期时间,如下面的代码;

var _time = new Date();//实例化一个时间对象
_time = _time.setTime(_time.getTime() + 30000);//30秒之后过期
document.cookie = "name=xiaoming;expires="+_time.toGMTString();

这条语句表示我们设置的cookie将在30秒之后过期!当我们此时打开页面,我们发现刚进来时,cookie那里有个name的键值对,但等待之后,name的键值对也不见了,此时再打印document.cookie,发现字符串中的name=xiaming也没有了!

点击我可产看全图

我们也可以设置一个过去的时间,让cookie立即无效,比如把上面的代码改成如下,那么将会在页面刚进来时就会对应的cookie无效。

_time = _time.setTime(_time.getTime() - 1000);

我们在赋值document.cookie的时候也可以设置它的使用域,也就是说这个cookie在那个域下使用,也可以设置它的目录地址,同样的道理,表示在网站的那个目录下使用。比如下面的代码:

document.cookie = "name1=xiaochen;path=/htmlArticlePage/css/";

上面这个代码,我将在css目录下使用这个cookie。

如果我的域名下有两个主机,比如,t1.applinzi.com和t2.applinzi.com。现在我想在t2.applinzi.com下设置一个t1.applinzi.com能访问的cookie,那么我可以设置domain=t1.applinzi.com,并把path设置为‘/’。如下代码所示:

document.cookie = "name1=xiaochen;domain=t1.applinzi.com;path=/";

domain不能设置为cookie文件所在服务器不同值的域名,也就是说,新浪不可以设置一个腾讯的cookie。

当然了,也可以设置secure,这个代表cookie和服务器之间以怎样一种协议传输,通常可设置为“secure”,或者为空,默认为空,相关传输协议等安全概念,可以搜索查阅!

实战

需求

我们希望用户第一次进入页面的,登记一次姓名,一个月之内用户在此进入页面,我们希望用户能看到能看到一个包含自己名字欢迎界面弹框!并且不用再次登录姓名,登记姓名按钮变不可用!

我们先来构建我们的dom结构。

我们来说一下这个需求的逻辑!当用户在表单里面填写好姓名,然后点击登记按钮的时候,这时候我们执行插入cookie操作,并且之后把按钮设置为不能用,一个月之后可用!当用户再次进入这个页面,一个月之内,用户都会看到欢迎语!

首先我们定义一个脚本中定一个可以设置cookie的函数,这个函数的功能大概是:可以设置键、键值、以及cookie过期时间,其代码大概如下:

this.setCookie = function(cKey,cValue,cExpires){
//定义一个时间对象
var _time = new Date();
//定义过期时间
_time.setTime(_time.getTime() + formatTime(cExpires));
document.cookie = cKey + "=" + escape(cValue) + ((cExpires == undefined || /^\s*$/.test(cExpires))? " ":";expires="+_time.toGMTString());
};

为了尽量减少向全局空间传输变量所带来的变量污染等问题,所以我们在代码中使用了闭包和即时函数等方法,相关概念可以查阅我的其他文档!

上面的代码用到一个函数format()。这个函数主要的作用是把传入的时间参数转化一个相等js毫秒时间,因为js时间默认单位是毫秒,比如用户传入了“1h”,那么formatTime('1h')将返回一个值为1*60*60*1000的数字,以此类推,这个函数的代码如下:

//定义一个格式化时间函数
function formatTime(time){
//如果未传入参数,或者为空 ,或者传入的参数不是时间格式的参数,那么直接返回空
var reg = /^\d+((\s*?)|(ms)|s|m|h|d)?$/;
if(time == undefined || !reg.test(time)){console.log("你输入时间格式不对!");return ' ';};
//去掉参数前后的空白符,如果有的话
time = time.replace(/(^\s+)|(\s+$)/,'');
switch(true){
case /^\d+$/.test(time):time = parseInt(time)*1000;break;
case /ms$/.test(time):time = parseInt(time);break;
case /s$/.test(time):time = parseInt(time) * 1000;break;
case /m$/.test(time):time = parseInt(time) * 60 * 10000;break;
case /h$/.test(time):time = parseInt(time) * 60 * 60 * 1000;break;
case /d$/.test(time):time = parseInt(time) * 24 * 60 * 60 * 1000;break;
default:return '';
};
return parseInt(time);
};

当然了,我们希望在表单中输入的内容尽量是我们我能控制的内容,所以我们在此约定,用户输入的名字格式:能包含空格,且必须包含字符和数字的除开空格符8到20个字符!可以包含下划线“_”。为此我们给出下面的代码:

name_input.onchange = function(){
var _v1 = this.value;
var _v = _v1.replace(/\s+/gim,'');
if(/^[_|a-zA-Z]{1}\w{7,19}$/.test(_v)){
if(/\d+/g.test(_v)){
remove_Class(this,'error');
}else{
add_Class(this,'error');
alert("至少包括一个数字!");
};
if(/[a-zA-Z]+/g.test(_v)){
remove_Class(this,'error');
}else{
add_Class(this,'error');
alert("至少包括一个字母!");
};
}else{
add_Class(this,'error');
alert("请输入以字母或下划线开头的包含数字、字母的8~20个姓名字符!");
};
};

上面代码中出现的两个函数add_Class()和remove_Class(),相信大家已经看出他们的用途了,现在把他们的代码展示如下:

//定义一个删除dom类的方法
function remove_Class(dom,_class){
var ctxt = dom.className.replace(/(^\s+)|(\s+$)/,'').split(/\s+/);
var newClass = [];
for(var i = 0,len = ctxt.length;i<len;i++){
if(ctxt[i]!=_class){
newClass.push(ctxt[i]);
};
};
dom.className = newClass.join(' ');
};
//定义一个给dom增加一个class的方法
function add_Class(dom,_class){
//在增加之前,我们希望如果原来已经有了,就不用增加了
var ctxt = dom.className.replace(/(^\s+)|(\s+$)/,'').split(/\s+/);
var num = ctxt.indexOf(_class);
if(num == -1){
dom.className += ' '+ _class;
}else{return;};
};

我们的大部分代码已经实现了差不多了,就差最后一步,用户点击登记按钮之后,向本地客户端插入一条cookie!于是代码如下:

name_button.onclick = function(){
//首先获取表单内容,如果为空,或者未定义,那么直接返回
if(!_nameBoolean){alert("请输入正确姓名!");return;};
var input_value = name_input.value;
//向浏览器插入一个cookie
setCookie("userRegisterName",input_value,'30d');
this.disabled = true;
};

此时,我们来看我们的功能是否正常。的确,我们发现我们的系统除了能正确对用户输入的字符串进行过滤外,并且确实向客户端插入了一条cookie。我们在表单里面输入“jianfeng_1”。再设置完cookie之后,我们的按钮也变得不可用,并且查看cookie,确实新增了一条数据,测试结果截图如下:

点击我可产看全图

好了,到此,我们设置cookie部分的逻辑已经全部完成了,现在可以设想一下,第二次用户进入页面时候欢迎语部分逻辑怎么实现!

我们希望用户再次进来的时候,需要获取cookie,所以我们需要一个得到cookie的函数,于是给出代码如下:

this.getCookie = function(cKey){
//因为打印document.cookie返回的是一个字符串
var c_start = document.cookie.indexOf(cKey);//得到匹配字符串的开始位置
if(c_start == -1){return;};//说明未设置cookie
c_start = c_start + cKey.length + 1;//将位置定位到键值所在的位置
c_end = document.cookie.indexOf(";",c_start);
if(c_end == -1) c_end = document.cookie.length;//如果未找到分号,说明这个键在cookie字符串最后
return unescape(document.cookie.substring(c_start,c_end));
};

为了加深印象,我写了第二种获取cookie键值的方法!代码如下(使用了正则表达式):

this.getCookie_2 = function(cKey){
var setCookieBoolean = document.cookie.indexOf(cKey);
if(setCookieBoolean == -1)return;//说明未设置cookie
var reg = new RegExp("(^|;)"+cKey+"=([^;]*);?");
var arr = document.cookie.match(reg);
return unescape(arr[2]);
};

我们通过下面的代码,看下能不能得到cookie!

//获取cookie
var userRName = getCookie_2('userRegisterName');
console.log(userRName);

截图如下:

点击我可产看全图

我们发现确实能准确获取到对应的cookie值,现在我们就可以利用这个cookie来进行一些操作了!

我们首先要禁用按钮!使用如下代码:

function cookieMoreOperate(){
if(!userRName)return;
//禁用按钮
var name_button = document.getElementById("register_name_button");
name_button.disabled = true;
};
cookieMoreOperate();

同时我们希望设置欢迎语界面,代码如下:

function cookieMoreOperate(){
if(!userRName)return;
//禁用按钮
var name_button = document.getElementById("register_name_button");
name_button.disabled = true;
var _div = document.createElement('div');
_div.className = 'cookie_test_welcome_block';
var textNode = document.createTextNode("欢迎你在此到来,我的朋友"+userRName+'!');
_div.appendChild(textNode);
document.body.appendChild(_div);
};
cookieMoreOperate();

我们这样一个需求到这一步,已经算是基本完成!当然了,后期代码优化,在此不做深究!为了让大家对整体思路又一个了解,我把全部代码截图如下:

点击我可产看全图

相信大家对这篇文章的一个学习,一定会对cookie有些了解和帮助的!

后面内容持续更新………………………………