原生cookie

时间:2023-03-08 16:15:42

出于浏览器的安全性限制,从WEB应用程序中访问用户本地文件系统是有许多限制的。但是WEB站点的开发人员可以使用cookie,将少量信息保存在用户本地硬盘的指定空间中。

document对象的cookie属性。使用这个属性,可以在javascript代码中创建cookie,访问cookie中的数据。

打开cookie文件是非常安全的,因为它们只是简单的文本文件。

每个网站或域名都有一个自己的文本文件,以保存该站点的所有cookie。

在浏览器中cookie的内容看起来是一些混乱的字符,在编写cookie的时候,会发现无须采用这种格式设置cookie的信息。

cookie不在浏览器之间共享,因此在使用IE访问某个网站时保存的cookie不能用于其他浏览器,反之亦然。

cookie字符串:

创建cookie时,可以设置6个部分:

name(名称),value(值),expires(过期时间),path(路径),domain(域),和secure(安全性),后四个是可选。

1:名称和值:

名称用来引用cookie,值是cookie的信息部分。

document.cookie="name=value;";

名称和值是必选的。如果不存储名称或值,则cookie无效的。

cookie的值是一个基本字符串,如果保存数值数据,那么该字符串就是数字字符。特殊字符要用编码。

如果没有设置过期时间,cookie就在用户关闭浏览器后过期。下次用户打开浏览器时,该cookie便不复存在了。

2:过期时间:

如果希望cookie存在的时间比单个回话更长,则需要使用cookie的过期时间。

document.cookie="name=value;expires=THE,28 Dec 2020 00:00:00 GMT;";

上述代码设置的cookie在2020年12月28日之前是可用的。

注意:过期日期的格式很重要,它应与toGMTString()方法给出的cookie的格式相同。

实际上,可以使用Date对象获取当前日期,再将cookie设置为该日期后的3个月过期,否则就需要在2020.12.28重写页面。

var expirDate=new Date();
expirDate.setMonth(expirDate.getMonth()+3);
document.cookie="name=value;expires="+expirDate.toGMTString()+";";

上述代码创建一个cookie,名称为name,值为value,在当前日期后3个过期。但其他因素可能导致cookie在过期日期之前就失败,如用户删除了cookie,或者到达了cookie数量的上限。

3:路径:

在99%的情况下,都仅需要设置cookie的name,value,和expires部分。

web服务器常常就将整个网站合理划分为不同的目录,而不是放在一个web目录中。

cookie不仅特定与某个web域,还特定与该域中的具体路径。如www.mysite.com/mybooks/中的页面设置了一个cookie,那么只有该目录或其子目录的页面才能读取和修改这个cookie。如果www.mysite.com/mylist/下的页面试图读取这个cookie,则会失败。因为cookie是特定于具体路径的,所以在mybooks/目录下设置的cookie不能由mylist/目录下的页面访问。

例如在域www.mysite.com/mybooks/下有两个子目录www.mysite.com/mybooks/mybook01和www.mysite.com/mybooks/mybook02

若我设置

document.cookie="name=value;expires="+expirDate.toGMTString()+";path=/mybooks";

那么即使cookie是在目录mybook01下设置的,仍能有mybooks目录及其子目录中的页面访问。

如果要指定cookie可用于设置它的域的所有子目录,则可以用"/"字符指定根目录的路径。

document.cookie="name=value;expires="+expirDate.toGMTString()+";path=/";

现在,该cookie就可以供设置它的域下的所有目录访问。如果该域包含多个站点,则最好不好这样设置,否则其中的网站就可以访问这个cookie信息。

某人使用当前目录及其子目录。

4:域

默认的情况下,cookie仅用于设置它的域下的页面。在大多情况下,这是我们想要的。如果不想要这样,那么可以通过cookie的domain部分指定cookie可用于某个域下的所有子目录。

document.cookie="name=value;expires="+expirDate.toGMTString()+";path=/mybooks;domain=mydomain.com;";

上述代码可以由www.myweb01.mydomain.com和www.myweb02.mydomain.com内共享但不能由www.mydomain.com和www.myweb02.com因为它们的域名不同。

5:安全

cookie字符串的最后一部分是secure,是一个布尔值,设置为true则cookie仅发送给尝试使用安全通道检索它的web服务器(SSL建立服务器)。默认是false,总是发送cookie而不考虑安全性。

创建cookie

function setCookie(cookieName,cookieValue,cookiePath,cookieExpirse){
cookieValue=escape(cookieValue);
if(cookieExpirse==""){
         var nowDate=new Date();
         nowDate.setMonth(nowDate.getMonth()+6);
         cookieExpirse=nowDate.toGMTString();
}
if(cookiePath!=""){
cookiePath=";path="+cookiePath;
}
document.cookie=cookieName+"="+cookieValue+";expires="+cookieExpirse+cookiePath;
} setCookie("name1","rose1","","");
setCookie("name2","rose2","","");
setCookie("name3","rose3","10 May 2018","/")
alert(document.cookie)

保存文件到本地服务器上查看

原生cookie

可以看到三个cookie都显示为名称/值对,并用“;”分号来分隔,但是没有显示过期日期,路径也没有显示出来。

cookie的名称最好只使用字符和数字,没有空格,标点符号或特殊字符。

删除已有的cookie:

只需要修改cookie的值为空,并将其过期时间设置为一个过去了的时间。

setCookie("name3","","10 May 2000","")

获取cookie的值

使用document.cookie属性来获取cookie有两个局限性:

  1. 只是得到名称/值对,无法获得cookie的expires,path,domain和secure部分。
  2. 仅允许获取为某一路径和web服务器设置的所有cookie,只能一次性获取当前域和路径设置的所有cookie,无法获取指定名称的cookie(可以通过多种方法获取单个cookie,如字符串处理技术,从返回的字符串中截取需要的信息)

现在,编写代码获取单个cookie的值。该代码适用于所有支持cookie的浏览器。
function getcookieValue(cookieName){
var cookieValue=document.cookie;
var cookieStartAt=cookieValue.indexOf(" "+cookieName+"=");
if(cookieStartAt==-1){
cookieStartAt=cookieValue.indexOf(cookieName+"=");
}
if(cookieStartAt==-1){
cookieValue=null;
}else{
cookieStartAt=cookieValue.indexOf("=",cookieStartAt)+1;
var cookieEndAt=cookieValue.indexOf(";",cookieStartAt);
if(cookieEndAt==-1){
cookieEndAt=cookieValue.length;
}
cookieValue=unescape(cookieValue.substring(cookieStartAt,cookieEndAt));
}
return cookieValue;
}

获取document.cookie字符串,并保存在变量cookieValue中。

var cookieValue=document.cookie;该变量返回的是所有cookie列表:名称:值;每个cookie以“;”分号分隔。

在cookieValue字符串中查找形参cookieName的cookie的位置。该方法返回找到的cookie的字符位置。我们开始查找的是" "+cookieName+"=",前面有空格是为了不匹配第一个cookie(因为第一个cookie前面没有空格)。如果返回的结果cookieStartsAt是-1,则表示该cookie不存在,或者该cookie位于cookie字符串的开头(这时该cookie名称前也就不含空格所以不匹配返回-1)。
var cookieStartsAt=cookieValue.indexOf(" "+cookieName+"=");

为了确定是哪一种情况,需要进一步查找,这次查找不包含空格。
cookieStartsAt.cookieValue.indexOf(cookieName+"=");

如果都没有找到则将变量cookieValue设置为null。
cookieValue=null;

如果找到前面为没有空格的名称为形参cookieName的cookie或者直接找到了前面为空格的名称为形参cookieName的cookie。就开始在document.cookie字符串中截取该cookie的值。
现在需要找到该cookie值部分的开头和结尾。
其开头是cookie名称和“=”后的下一个字符位置。
下面始字代码indexOf()方法从cookie名称/值对的起符开始搜索,查找字符串中跟在cookie名称后面的等号的位置再+1。
cookieStartsAt=cookieValue.indexOf("=",cookieStartsAt)+1;

var cookieEndAt=cookieValue.indexOf(";",cookieStartAt);

结尾位置是形参(名称)“;“分号的位置。

原生cookie

以上图为例子,假设上面就是通过document.cookie找到的所有的cookie。

我们把name2作为参数传入,也就是通过getcookieValue()函数获取name2的值。

var cookieStartAt=cookieValue.indexOf(" "+cookieName+"=");

从cookie列表中从头到尾找到“空格name2=”的位置。

此时 cookieStartAt的值为12,即name2前一个空格位置(位置从0开始算)

关于的用法请查看javascript知识总汇

我们的代码首先查找参数(name2)前面有空格的,发现找到了也就是不为-1然后代码跳过了以下几个步骤直接到截取代码部分。

我们先找到要截取的开始位置。

cookieStartAt=cookieValue.indexOf("=",cookieStartAt)+1;

从name2后开始找到第一个出现“=”的位置+1

此时cookieStartAt为18+1=19,即name2后面的”=“号位置+1(不包含等号)

然后到了结束位置

var cookieEndAt=cookieValue.indexOf(";",cookieStartAt);

从19的位置开始找第一个出现“;”位置。这里是24.

最后截取的位置就是19到24之间的所有字符,从0开始算起,substring()方法的第一个参数截取时包括在内,第二个参数截取时不包括在内。

cookieValue=unescape(cookieValue.substring(cookieStartAt,cookieEndAt));

完整代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script>
function setCookie(cookieName,cookieValue,cookieExpires,cookiePath){
cookieValue=escape(cookieValue);
if(cookieExpires==""){
var nowDate=new Date();
nowDate.setMonth(nowDate.getMonth()+6);
}
if(cookiePath!=""){
cookiePath="Path="+cookiePath;
}
document.cookie=cookieName+"="+cookieValue+";expires="+cookieExpires+cookiePath;
}
// setCookie("oo","pp","","");
// alert(document.cookie)
function getcookieValue(cookieName){
var cookieValue=document.cookie;
var cookieStartAt=cookieValue.indexOf(" "+cookieName+"=");
if(cookieStartAt==-1){
cookieStartAt=cookieValue.indexOf(cookieName+"=");
}
if(cookieStartAt==-1){
cookieValue=null;
}else{
cookieStartAt=cookieValue.indexOf("=",cookieStartAt)+1; var cookieEndAt=cookieValue.indexOf(";",cookieStartAt);
if(cookieEndAt==-1){
cookieEndAt=cookieValue.length;
}
cookieValue=unescape(cookieValue.substring(cookieStartAt,cookieEndAt));
}
return cookieValue;
}
var list=getcookieValue("name2");
alert(list) setCookie("name1","rose1","","");
setCookie("name2","rose2","","");
setCookie("name3","rose3","","");
</script> </body>
</html>

cookie的局限性:

1:用户可能禁用cookie

尽管所有现代浏览器都支持cookie,但用户可能禁用了它们。

大多数用户都默认启用会话cookie,会话cookie是仅在用户浏览网站期间存在的cookie,用户关闭浏览器后,该cookie就被清除。通常还启用了更持久的cookie。但是,第三方cookies(来自第三方站点)通常是禁用的,它们用于跟踪用户对不同网站的访问,因此人们对这种cookie是侵犯隐私的。

禁用cookie时,前面用于创建cookie和获取cookie值的函数不会报错,但是所获取cookie的值为null.

这个时候主动检查是否启用了cookie,如果未启用,则采取相应的应对措施,如将用户重定向到一个不需要使用cookie的简化页面。

if(getCookieValue("name")==null){
alert("网站需要启用cookie")
}

2:数字和信息的限制

能在用户计算机上为某个网站设置的cookie的数量是有限的,每个cookie能保存的信息也是有限的。在早起的浏览器中,最多只能为每个域保存20个cookie,每个cookie的名称/值对不超过4096字节。另一个要点是,所有浏览器都设置了能保存cookie总数的上限。到达这个限制时,无论是否过期,都会删除一些旧的cookie。现代浏览器(IE7+和其他浏览器)支持的cookie总数为50个,但具体的数字在不同的浏览器中有些出入。但为了突破cookie总数的限制,可以在一个cookie中保存多条信息。

setCookie("userdetails","rose;22;10 Jan 2001","","");
var cookieValue =getCookieValue("userdetails");
cookieValue=cookieValue.split(";");
alert("name"+cookieValue[0]);
alert("age"+cookieValue[1]);
alert("last vistie"+cookieValue[2]);

由于在setCookie()函数中用escape()方法转义了cookie的值,因此cookie中的值中的分号不会与其他部分中的分号混淆。在使用getCookieValue()函数返回该cookie值时,只需将它拆分成各组成部分即可,但是要注意的是,各部分的存储顺序要记住。那么现在还有19个cookie可用。