cookie
简言之,session是存储在服务器端的,cookie是存储在客户端的,session可以依赖于cookie。
cookie机制。正统的cookie分发是通过扩展HTTP协议来实现的,服务器通过在HTTP的响应头中加上一行特殊的指示以提示
浏览器按照指示生成相应的cookie。然而纯粹的客户端脚本如JavaScript或者VBScript也可以生成cookie。而cookie的使用
是由浏览器按照一定的原则在后台自动发送给服务器的。浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围
大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。
cookie知识点 | 描述 |
cookie的内容 | 名字,值,过期时间,路径和域。路径与域一起构成cookie的作用范围 注:可以保存中文和二进制 |
过期时间 | 1) 若不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,关闭浏览器窗口,cookie就消失。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里 2) 若设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。(存储在硬盘上的cookie可以在不同的浏 览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式) |
多个浏览器共享 | 存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。 而对于保存在内存里的cookie,不同的浏览器有不同的处理方式 |
安全性 | 存储在内存中的cookie比存储在硬盘上的cookie安全 |
分类 | 内存中的cookie(该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效) 硬盘上的cookie |
保存方式 | Cookie实际上是一小段的文本信息 不同的浏览器有不同的方式 |
Cookie的不可跨域名性 | 1) Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。 2) 不同域名不可访问,修改其他域名的cookie 注意:用户登录网站www.google.com之后会发现访问images.google.com时登录信息仍然有效,而普通的Cookie是做不到的。这是因为Google做了特殊处理。 |
cookie具体交互
step 1: 当用户使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器(首次访问服务器,此时还没有建立cookie);
step2: 接着,(如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie)服务器在向客户端回传相应的超文本的同时也会发回这些个人信息(cookie),当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header);
step 3: 当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置(内存或硬盘)
step 4: 客户端再向服务器发送请求的时候,都会把相应的Cookie再次发回至服务器。而这次,Cookie信息则存放在HTTP请求头(Request Header)了。
step 5: 服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息(服务器检查该Cookie,还可以根据需要修改Cookie的内容,以此来辨认用户状态),从而动态生成与该客户端相对应的内容。通常,我们可以从很多网站的登录界面中看到“请记住我”这样的选项,如果你勾选了它之后再登录,那么在下一次访问该网站的时候就不需要进行重复而繁琐的登录动作了,而这个功能就是通过Cookie实现的。
注意:
1) 只运行某域名能用cookie:cookie.setDomain
2) 只允许某路径用cookie:cookie.setPath ,如只允许/sessionWeb/下的程序使用Cookie
3)设置安全:cookie.setSecure(true)。不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。
cookie命令 | 例子 |
document.cookie | 所有cookie |
document.cookie="userId=828"; document.cookie="userId=828; userName=hul; | 设置 |
document.cookie="str="+escape("I love ajax"); 相当于 document.cookie="str=I%20love%20ajax"; 取出值以后需要使用unescape()进行解码 | 在cookie 的名或值中不能使用分号(;)、逗号(,)、 等号(=)以及空格。 在cookie的名中做到这点很容易,但要保存的值是不确定的。 如何来存储这些值呢? 方 法是用escape()函数进行编码, 它能将一些特殊符号使用十六进制表示, 例如空格将会编码为“20%”,从而可以存储于cookie值中, 而且使用此 种方案还可以避免中文乱码的出现。 |
//获取当前时间 var date=new Date(); var expiresDays=10; //将date设置为10天以后的时间 date.setTime(date.getTime()+expiresDays*24*3600*1000); //将userId和userName两个cookie设置为10天后过期 document.cookie="userId=828; userName=hulk; expires="+date.toGMTString(); | 要将cookie设置为10天后过期 |
//获取当前时间
效果: document.cookie已经查不到了 | 删除一个cookie,可以将其过期时间设定为一个过去的时间 |
document.cookie="userId=320; path=/"; 根目录 | 指定可访问cookie的路径 默认:默 认情况下,如果在某个页面创建了一个cookie,那么该页面所在目录中的其他页面也可以访问该cookie。如果这个目录下还有子目录,则在子目录中也 可以访问。 |
以google为例,要实现跨主机访问,可以写为:所有google.com下的主机都可以访问该cookie document.cookie="name=value;domain=.google.com"; | 指定可访问cookie的主机名 主机名是指同一个域下的不同主机,例如:www.google.com和gmail.google.com就是两个不同的主机名。默认情况下, 一个主机中创建的cookie在另一个主机下是不能被访问的,但可以通过domain参数来实现对其的控制 |
注: 增加 function addCookie(name,value,expiresHours){ var cookieString=name+"="+escape(value); //判断是否设置过期时间 if(expiresHours>0){ var date=new Date(); date.setTime(date.getTime+expiresHours*3600*1000); cookieString=cookieString+"; expires="+date.toGMTString(); } document.cookie=cookieString; } 获取 function getCookie(name){ var strCookie=document.cookie; var arrCookie=strCookie.split("; "); for(var i=0;i<arrCookie.length;i++){ var arr=arrCookie[i].split("="); if(arr[0]==name)return arr[1]; } return ""; } 删除 function deleteCookie(name){ var date=new Date(); date.setTime(date.getTime()-10000); document.cookie=name+"=v; expires="+date.toGMTString(); } | 增删改查 参考: http://www.w3school.com.cn/js/js_cookies.asp |
方法一: function clearme(){ var cookies = document.cookie.split(";"); for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i]; var eqPos = cookie.indexOf("="); var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; } if(cookies.length > 0) { for (var i = 0; i < cookies.length; i++) { var cookie = cookies[i]; var eqPos = cookie.indexOf("="); var name = eqPos > -1 ? cookie.substr(0, eqPos) : cookie; var domain = location.host.substr(location.host.indexOf('.')); //www.baidu.com---> baidu.com document.cookie = name + "=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=" + domain; } } } 方法二 http://www.jb51.net/article/25405.htm 方法不行 function clearCookie(){ var keys=document.cookie.match(/[^ =;]+(?=\=)/g); if (keys) { for (var i = keys.length; i--;) document.cookie=keys[i]+"=;expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/"; //也可加上 domain | 清除所有cookie |
参考:
http://www.jb51.net/article/67141.htm
session机制
session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否已包含了一个session标识
(称为session id),如果已包含则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来
使用(检索不到,会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相
关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应
中返回给客户端保存。
注意点:
1) 保存session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发送给服务器。
一般这个cookie的名字都是类似于SEEESIONID。
2) 如果cookie被禁止,为保证能够把session id传递回服务器,有如下方法:
方法一:URL重写,就是把session id直接附加在URL路径的后面.
例如:
<td>
<a href="<%=response.encodeURL("index.jsp?c=1&wd=Java") %>">
Homepage</a>
</td>
该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。重写后的输出可能是这样的:
<td>
<a href="index.jsp;jsessionid=0CCD096E7F8D97B0BE608AFDC3E1931E?c=1&wd=Java">Homepage</a>
</td>
把session id直接附加在URL路径的后面,附加方式也有两种:
方法一:
作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid= ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
方法二:
作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。
方法二:表单隐藏字段。就是服务器
会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
误解:只要关闭浏览器,session就消失了
对session来说也是一样的,除非程序通知服务器删除一个session,否则服务器会一直保留,程序一般都是在用户做log off的时候发个指令去删除session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分session机制都使用会话cookie来保存session id,而关闭浏览器后这个 session id就消失了,再次连接服务器时也就无法找到原来的session。如果服务器设置的cookie被保存到硬盘上,或者使用某种手段改写浏览器发出的HTTP请求头,把原来的session id发送给服务器,则再次打开浏览器仍然能够找到原来的session。
恰恰是由于关闭浏览器不会导致session被删除,迫使服务器为seesion设置了一个失效时间,当距离客户端上一次使用session的时间超过这个失效时间时,服务器就可以认为客户端已经停止了活动,才会把session删除以节省存储空间。
注意:
1) session的生命周期。
Session保存在服务器端。为了获得更高的存取速度,服务器一般把Session放在内存里。每个用户都会有一个独立的Session。如果Session内容过于复杂,当大量客户访问服务器时可能会导致内存溢出。因此,Session里的信息应该尽量精简。
Session在用户第一次访问服务器的时候自动创建。需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session。如果尚未生成Session,也可以使用request.getSession(true)强制生成Session。
Session生成后,只要用户继续访问,服务器就会更新Session的最后访问时间,并维护该Session。用户每访问服务器一次,无论是否读写Session,服务器都认为该用户的Session“活跃(active)”了一次。
2) session的有效期
由于会有越来越多的用户访问服务器,因此Session也会越来越多。为防止内存溢出,服务器会把长时间内没有活跃的Session从内存删除。这个时间就是Session的超时时间。如果超过了超时时间没访问过服务器,Session就自动失效了。
具体例子--怎么才能实现网上商店中的购物车
session就是一种保存上下文信息的机制,它是针对每一个用户的,变量的值保存在服务器端,通过SessionID来区分不同的客户;
session是以cookie或URL重写为基础的,默认使用cookie来实现,系统会创造一个名为JSESSIONID的输出cookie,我们叫做session cookie,以区别persistent cookies,也就是我们通常所说的cookie;
注意
1) session cookie是存储于浏览器内存中的,并不是写到硬盘上的,这也就是我们刚才看到的JSESSIONID,我们通常情是看不到JSESSIONID的
2) 但是当我们把浏览器的cookie禁止后,web服务器会采用URL重写的方式传递Sessionid,我们就可以在地址栏看到sessionid=KWJHUG6JJM65HS2K6之类的字符串。
3)
persistent cookie只是存在于客户端硬盘上的一段文本(通常是加密的),而且可能会遭到cookie欺骗以及针对cookie的跨站脚本攻击,不如session cookie安全;
4)
通常session cookie是不能跨窗口使用的,当你新开了一个浏览器窗口进入相同页面时,系统会赋予你一个新的sessionid,这样我们信息共享的目的就达不到了,此时我们可以先把sessionid保存在persistent cookie中,然后在新窗口中读出来,就可以得到上一个窗口SessionID了,这样通过session cookie和persistent cookie的结合我们就实现了跨窗口的session tracking(会话跟踪)。
区别
区别 | session | cookie |
端/目的 | 而session机制采用的是一种在客户端与服务器之间保持状态的解决方案。 注: 由于采用服务器端保持状态的方案在客户端也需要保存一个标识, 所以session机制可能需要借助于cookie机制来达到保存标识的目的,但实际上它还有其他选择。 | cookie机制采用的是在客户端保持状态的方案 cookie的作用就是为了解决HTTP协议无状态的缺陷所作的努力 |
存放 | 放在服务器 | 存放在客户的浏览器 |
安全性 | 考虑到安全应当使用session | cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗 |
性能 | session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能 | 不影响服务器性能 由于浏览器每次请求服务器都会携带Cookie,因此Cookie内容不宜过多,否则影响速度。Cookie的内容应该少而精 |
大小 | 无 | 单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie |
使用建议 | 将登陆信息等重要信息存放为SESSION | 其他信息如果需要保留,可以放在COOKIE中 |
测试与cookie
测试时,要检查以下方面:
1) cookie的正确性
2) cookie的有效期
3) 禁用cookie的情况
参考
http://www.cnblogs.com/shiyangxt/archive/2008/10/07/1305506.html
http://blog.sina.com.cn/s/blog_59e16a4d0100q3yn.html
http://my.oschina.net/xianggao/blog/395675