曾经,我非常羡慕那些人见人爱的人,我也想要变成那样,可是后来我才明白人见人爱也是需要天赋的,后来我开始默默努力,我想,就算我不能让每个人都喜欢我,至少因为我做的努力能得到别人的尊重。

客户端与服务器cookie

认识cookie

第一部分: 概要

  cookie是一种早期使用的客户端存储机制(现在仍在广泛使用),cookie数据会在Web浏览器和Web服务器之间传输, 因为早期cookie是针对服务器脚本设计的,所以服务端脚本可以读、写存储在客户端的cookie的值。 值得注意的是, 任何以cookie形式存储的值,无论服务器端是否需要,每一个HTTP请求都会把这些数据(cookie数据)传输到服务器端。但是cookie的存储量较小,一般不得超过4kb,即4096个字节。由于存储能力较弱,现在比较流行的是WebStorage,

  Cookie是访问过的网站创建的文件,用于存储浏览器信息,例如个人资料。

  cookie的缺点

  • 数据存储大小:4kb,作为数据存储容器,却只有4kb,对于目前稍微有一些繁杂的页面,cookie就不够用了。
  • 安全性问题: cookie是在HTTP中明文传递的(HTTPs不是,这和协议有关,与cookie本身无关),所以说这是非常不安全的。
  • 网络负担: 之前提到cookie会随着HTTP请求在web浏览器和服务器间传递,这是非常浪费带宽的。

  HTTP Cookie,通常直接叫做cookie,标准要求服务器将Set-Cookie作为响应的一部分,其中包含会话信息,这种服务器响应报文的首部字段可能如下,其中以name为名称、以value为值,这是要求客户端发送name这个键名的cookie值,如下:

HTTP/1.1 200 OK
Content-type: Text/html
Set-Cookie: name=value
Other-header: other-header-value

   那么浏览器端的请求就是这样的:

GET /index.html HTTP/1.1
Cookie: name=value
Other-header: other-header-value

  即把服务器需要的name的值发送到服务器端。

  将cookie发送到服务器可以使得服务器知道关于此用户的更多信息。

    注意: 每一个cookie的格式都是这样的: <cookie名> = <值>; 名称和值都必须是合法的标识符。

   注意: cookie是存在有效期的, 在默认情况下,cookie的声明周期就是在浏览器关闭的时候结束,如果想要使得cookie在浏览器关闭之后还可以用,就要为cookie设置有效期,也就是cookie的实效日期。

补充: 上面的cookie有效期说法是有问题的,不是说浏览器关闭的时候结束。 比如mail.qq.com这个网站,当我们输入密码登录之后,即使关闭了这个浏览器,然后在另外一个一直存在chrome浏览器中再打开mail.qq.com,发现还是可以直接使用而无需登录的。 但是呢,如果再我们登录之后,一下关闭掉所有的chrome浏览器,然后再打开,就发现,确实需要重新输入了,这便是一个cookie的生存周期。 下面进行验证:

   我们打开chrome浏览器,最开始一般就是一个空的标签页,然后去看与chrome有关的进程数,可以看到最开始有10个左右,

      然后我们在打开几个标签页,如下所示:

  然后再去看chrome的进程数,可以发现现在大约是15到16个,接下来,我们把这些标签页分开,如下所示:

       

  然后再去看进程数,发现并没有变化,所以说,浏览器的生命周期不是说创建一个新的窗口就是一个新的生命周期,而是所有的标签,一旦所有的chrome浏览器的标签都关闭了,那么chrome的生命周期也就结束了。

 

 

 

 

 

 

 

 

 

第二部分:cookie查看

  我们可以使用 console.log(window.navigator.cookieEnabled) 查看我们自己浏览器的cookie功能是否打开,它返回一个布尔值,如果为true就说明打开了。 

  如果打开chrome的内容设置中的“阻止网站设置任何数据”这样我们使用上面的代码,就可以发现cookie功能关闭了,即false。这时,客户端就不会再存储任何cookie了。

  实际上cookie就是一些字符串信息,这些信息放在客户端的计算机上,用于客户端计算机和服务器之间传递信息。我们可以使用 alert(typeof document.cookie) 来检测

  在JavaScript中可以通过 document.cookie 来读取或设置这些信息,由于cookie 多用在客户端和服务器之间传递信息,所以除了JavaScript之外,服务器端的语言如PHP也可以存取cookie。

   由于cookie最终都是以文件形式存放在客户端,所以查看和修改cookie都是十分方便的,这就是为什么常说cookie不能存放重要信息的原因。 

有时候,在服务器发送set-Cookie字段时,即要求浏览器携带上某些cookie,以便下次再请求的时候可以防止再次登录等。除了key-value,还可以在服务器端设置好 httponly,这样,用户就不能通过 document.cookie 进行xss攻击了。   

 

 

 

第三部分: 关于cookie的一些限制 

  cookie有 域和路径 这个概念。域就是domin 的概念,因为浏览器是一个主意安全的环境,所以不能域之间必然是不能互相访问cookie的(当然可以通过跨域的方式做到就向jsonp),路径就是routing的概念,一个网页所创建的cookie只能被与这个网页在同一目录或子目录下的网页访问,而不能被其他目录下的网页访问

   

 

  

 

第四部分: Cookie常见问题

cookie存在两种类型

  • 你浏览的当前网站设置的cookie。
  • 来自网页上嵌入广告或图片等其他域来源的第三方cookie(网站通过使用这些cookie可以跟踪你的使用信息)  

Cookie的声明周期大致可以分为两种状态:

  • 其一: 即临时性质的cookie, 当前使用的过程中网站会储存一些你的个人信息,后面就用不到了,所以浏览器关闭之后这些信息就从计算机中删除。
  • 其二: 设置了失效时间的cookie,比如你的用户名和密码通过cookie李记录,这样就不需要每次都自己输入后登陆而是直接登陆了。 可以设置保留几天、几十天等。

Cookie的两种清除方式

  • 浏览器自身的设置中清除
  • 通过设置cookie的有效期
  • 说明: 删除cookie有可能导致某些网页无法正常运行(如:我将cookie功能关闭,现在写的博文就不能正常提交)

浏览器可以通过设置接受或拒绝访问cookie,处于性能和功能的考虑,尽量降低cookie的使用数量。

假如是本地磁盘中的页面,chrome的控制台是无法用JavaScript读写操作 cookie 的,解决办法...换一个浏览器^_^。

 

 

第五部分: cookie基础用法

一、 简单的存取操作

  使用js存取cookie时,必须使用document的cookie属性,如下:

document.cookie = 'username=zzw';

 注意: 其中username就是cookie的名称,zzw就是这个名称对应的值。 假设 cookie 名称并不存在,那么就是创建一个新的 cookie;如果存在就是修改了这个 cookie 名称对应的值。如果要多次创建 cookie ,重复使用这个方法即可。

  我们还可以通过document.cookie.length来查看有多少对这样的cookie。

 

二、 cookie的读取操作

  下面的代码是w3school上的例子

function getCookie(c_name){
    if (document.cookie.length>0){  //先查询cookie是否为空,为空就return ""
      c_start=document.cookie.indexOf(c_name + "=")  //通过String对象的indexOf()来检查这个cookie是否存在,不存在就为 -1  
      if (c_start!=-1){ 
        c_start=c_start + c_name.length+1  //最后这个+1其实就是表示"="号啦,这样就获取到了cookie值的开始位置
        c_end=document.cookie.indexOf(";",c_start)  //其实我刚看见indexOf()第二个参数的时候猛然有点晕,后来想起来表示指定的开始索引的位置...这句是为了得到值的结束位置。因为需要考虑是否是最后一项,所以通过";"号是否存在来判断
        if (c_end==-1) c_end=document.cookie.length  
        return unescape(document.cookie.substring(c_start,c_end))  //通过substring()得到了值。想了解unescape()得先知道escape()是做什么的,都是很重要的基础,想了解的可以搜索下,在文章结尾处也会进行讲解cookie编码细节
      } 
    }
    return ""
  }

  可以看得出来,这实际上就是对字符串进行操作。

 

 

三、设置cookie的有效期

  默认情况,cookie在浏览器关闭就实效了,但是我们可以通过下面的方式来设置有效期:

document.cookie = "name=value;expires=date"

  

  显然,这里的name=value是一个个的cookie对,而expires这个key是一个关键词,可以被唯一的识别出来,而不能作为一般的cookie来传递。

 

  上面的data值为GMT时间(格林威治时间)的日期型字符串,生成方式如下:

var _date = new Date();

_date.setDate(_date.getDate()+30);

_data.toGMTString();

  直接在本机上运行,结果是:"Fri, 21 Apr 2017 19:21:11 GMT"

  我们通过 +30 就可以设置cookie的有效时间是30天了。注意:setDate和getDate的使用。

 

 

第六部分: Cookie路径概念

  默认情况下,只有与创建 cookie 的页面在同一个目录或子目录下的网页才可以访问,这个是因为安全方面的考虑,造成不是所有页面都可以随意访问其他页面创建的 cookie。  

  如:在 "http://www.cnblogs.com/Darren_code/" 这个页面创建一个cookie,那么在"/Darren_code/"这个路径下的页面如: "http://www.cnblogs.com/Darren_code/archive/2011/11/07/Cookie.html"这个页面默认就能取到cookie信息,因为这个页面时上面的路径的子目录下的页面。而因为"http://www.cnblogs.com"或者 "http://www.cnblogs.com/xxxx/"不是在同一个目录下,所以不能访问cookie了。

  

 

 

第七部分: Cookie安全性

  之前说到,cookie在报文和本地文件中,都可以看到,所以不能存放重要的信息,他们都是不安全的。但是cookie中传递的内容非常重要,就要用加密的方式来传输数据。 

  即如果把cookie的属性名称为secure,默认的值为空,那么它和服务器之间就会通过https或其他的安全协议传输数据,如下:

document.cookie = "username=zzw;secure"

 值得注意的是: 这样只能保证cookie和服务器之间的数据传输是加密的,但是本地文件依旧没有加密。所以本地的cookie还是很容易看到的。

 

 

第八部分: cookie编码细节

  在输入cookie信息时不能包含空格、分号、逗号等特殊符号。 而在一般情况下,cookie都是采用未编码的方式。 所以,在设置cookie之前应当使用escape()函数先将cookie进行编码,在获取到cookie的时候使用unescapse()函数把值进行转换回来。

 

 

 

第九部分: cookie获取

  注意: 如果我们直接在本地创建一个html,那么通过document.cookie是不能进行设置和获取的,而必须在http的网页下才可以,就像我们测试跨域一样,在本地无法测试,而是只能在node服务器环境下进行测试。主要函数如下所示:

var myCookie = 'name=wayne;girfriend=hedy;object=marry;appearence=handsome;future=promising;children=11';

    function getCookie(myCookie, key) {
      if (typeof key != 'string' || typeof document.cookie != 'string') {
        console.error('输入参数格式错误!');
        return;
      } else if (key == '') {
        console.error('key不能为空!');
        return;
      }

      if (myCookie.length == 0) {
        console.error('cookie为空!');
        return;
      }
      var cookieArr = myCookie.split(';'),
          temp;
      for (var i = 0, len = cookieArr.length; i < len; i++) {
          temp = cookieArr[i].split('=');
          // 这里需要进行trim处理,否则会出现问题,因为cookie的key之前会添加空格。
          if (temp[0].trim() == key) {
            console.log(temp[1]);
            return;
          }
      }
      console.error(key + '不存在!');
      return;
    }

    getCookie(myCookie, 'name');

其中在函数内部的前面,我做了很多判断,因为输入可能是有问题的,对于全局异常处理要有很好的把控。

 

另外,这个函数也是可以直接在网站下使用的,如下:

 

 

 

 

 

 

 

 

 

参考文章:http://www.cnblogs.com/Darren_code/archive/2011/11/24/Cookie.html

http://www.cnblogs.com/xiaohuochai/p/6591392.html

posted @ 2017-03-23 02:41  Wayne-Zhu  阅读(1291)  评论(0编辑  收藏  举报

一分耕耘,一分收获。