认识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  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>){  //先查询cookie是否为空,为空就return ""
      c_start=document.cookie.indexOf(c_name + "=")  //通过String对象的indexOf()来检查这个cookie是否存在,不存在就为 -1  
      if (c_start!=-){
        c_start=c_start + c_name.length+  //最后这个+1其实就是表示"="号啦,这样就获取到了cookie值的开始位置
        c_end=document.cookie.indexOf(";",c_start)  //其实我刚看见indexOf()第二个参数的时候猛然有点晕,后来想起来表示指定的开始索引的位置...这句是为了得到值的结束位置。因为需要考虑是否是最后一项,所以通过";"号是否存在来判断
        if (c_end==-) 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 == ) {
console.error('cookie为空!');
return;
}
var cookieArr = myCookie.split(';'),
temp;
for (var i = , len = cookieArr.length; i < len; i++) {
temp = cookieArr[i].split('=');
// 这里需要进行trim处理,否则会出现问题,因为cookie的key之前会添加空格。
if (temp[].trim() == key) {
console.log(temp[]);
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

客户端与服务器cookie的更多相关文章

  1. 前端学HTTP之客户端识别和cookie

    前面的话 Web服务器可能会同时与数千个不同的客户端进行对话.这些服务器通常要记录下它们在与谁交谈,而不会认为所有的请求都来自匿名的客户端.本文主要介绍客户端识别及cookie机制 HTTP首部 HT ...

  2. 客户端技术:Cookie 服务端技术:HttpSession

    客户端技术:Cookie 服务端技术:HttpSession 07. 五 / android基础 / 没有评论   一.会话技术1.什么是会话:客户打开浏览器访问一个网站,访问完毕之后,关闭浏览器.这 ...

  3. 开源的C#实现WebSocket协议客户端和服务器websocket-sharp组件解析

    很久没有写博客了(至少自己感觉很长时间没有写了),没办法啊,楼主也是需要生活的人啊,这段一直都在找工作什么的.(整天催我代码的人,还望多多谅解啊,我会坚持写我们的项目的,还是需要相信我的,毕竟这是一个 ...

  4. 客户端缓存机制 - Cookie详解

    Cookie 作者:Stanley 罗昊 [转载请注明出处和署名,谢谢!] Cookie不是内置对象,所以用的时候需要new出来,Cookie是由服务端产生的,再发送给客户端保存,它不是内置对象,却是 ...

  5. 和我一起学《HTTP权威指南》——客户端识别与cookie机制

    客户端识别与cookie机制 服务器需要区别是哪个客户端. 个性化接触 HTTP是匿名.无状态的请求/响应协议. Web站点希望: 对客户端的用户有更多的了解 追踪用户浏览页面的行为 因此,产生了几种 ...

  6. HAProxy负载均衡保持客户端和服务器Session亲缘性的3种方式

    1 用户IP 识别  haroxy 将用户IP经过hash计算后 指定到固定的真实服务器上(类似于nginx 的IP hash 指令) 配置指令: balance source 配置实例: backe ...

  7. C#实现WebSocket协议客户端和服务器websocket sharp组件实例解析

    看到这篇文章的题目,估计很多人都会问,这个组件是不是有些显的无聊了,说到web通信,很多人都会想到ASP.NET SignalR,或者Nodejs等等,实现web的网络实时通讯.有关于web实时通信的 ...

  8. Android客户端与服务器

    就是普通的服务器端编程,还不用写界面,其实还比服务器编程简单一些.跟J2EE一样的服务器,你android这一方面只要用json或者gson直接拿数据,后台的话用tomcat接受请求操作数据,功能不复 ...

  9. Socket与SocketServer结合多线程实现多客户端与服务器通信

    需求说明:实现多客户端用户登录,实现多客户端登录一般都需要使用线程技术: (1)创建服务器端线程类,run()方法中实现对一个请求的响应处理: (2)修改服务器端代码,实现循环监听状态: (3)服务器 ...

随机推荐

  1. POJ3020 Antenna Placement(二分图最小路径覆盖)

    The Global Aerial Research Centre has been allotted the task of building the fifth generation of mob ...

  2. Python中多使用迭代器

    英文原文出处:Use More Iterators 本文介绍将代码转换为使用迭代器的原因和实用技巧. 我最喜欢的Python语言的特色之一是生成器,它们是非常有用的,然而当阅读开源代码时,我很少遇到它 ...

  3. java學習書

    轉載 成为Java顶尖程序员 ,看这11本书就够了 以下是我推荐给Java开发者们的一些值得一看的好书.但是这些书里面并没有Java基础.Java教程之类的书,不是我不推荐,而是离我自己学习 Java ...

  4. 正则表达式回溯-导致CPU偏高

    最近了解了下有关正则表达式回溯的内容,想想就写下来,方便自己. 正则表达式匹配算法是建立在正则表达式引擎的基础上的,目前有两种引擎:DFA(确定型有穷自动机)和NFA(不确定型有穷自动机).这两种引擎 ...

  5. 端口以及服务常用cmd

    netstat -ano                           列出所有端口的情况 netstat -aon|findstr "49157"   查出特定端口的情况 ...

  6. fwrite()

    注:fwrite(),fread -可对数据块读写,且数据为二进制,文本下查看为乱码,文件的打开方式为 “b*” 实例: 写入二进制数据 for (int i = 0; i < SN; i++) ...

  7. iOS 开发技术体系

    iOS 开发技术体系图: - 层级 | 主要框架 - ---------------------|--------------------------------------------------- ...

  8. 「BZOJ 2342」「SHOI 2011」双倍回文「Manacher」

    题意 记\(s_R\)为\(s\)翻转后的串,求一个串最长的形如\(ss_Rss_R\)的子串长度 题解 这有一个复杂度明显\(O(n)\)的做法,思路来自网上某篇博客 一个双倍回文串肯定当且仅当本身 ...

  9. conda install 安装太慢怎么办?

    小编我在安装tensorflow和keras的过程中,安装进程太慢,小木棍一直在转圈...抓狂... 如何解决??? 使用清华提供的anaconda镜像,使用以后真的很快! Anaconda 镜像使用 ...

  10. loj #2305. 「NOI2017」游戏

    #2305. 「NOI2017」游戏 题目描述 小 L 计划进行 nnn 场游戏,每场游戏使用一张地图,小 L 会选择一辆车在该地图上完成游戏. 小 L 的赛车有三辆,分别用大写字母 AAA.BBB. ...