浅谈cookie机制

来源:互联网 发布:java开源框架是什么 编辑:程序博客网 时间:2024/06/11 10:48

1.  为什么会有cookie机制?

会话是通过http协议进行通信的,但http协议是一种无状态协议(即当浏览器向服务器发送一次请求,服务器响应请求之后通信便结束),若同一个浏览器在一个网站上面请求多次本网站的其它资源,则每次都需建立浏览器与服务器的连接。这样就意味着服务器无法从连接上跟踪服务器。

Cookie就是这样的一种机制它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。

2.  什么是cookie?

   其实,简单来说,cookie就是一段小的文本信息。当用户通过(无状态)http协议访问服务器时,服务器都会给用户一个cookie,来记录用户信息。

客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。

注意:cookie需要浏览器支持,不同浏览器使用不同方式保存cookie。


3. cookie怎么用?

3.1 记录用户访问次数

Java把cookie封装成一个javax.servlet.http.Cookie类,每个cookie都是该类的对象。服务器通过操作cookie类对象来对每个客户端浏览器cookie对象进行操作。主要操作有:通过request.getCookie()来得到客户端的所有cookie对象信息(以cookie[ ]数组形式返回);通过response.addCookie(Cookie  cookie)对客户端cookie类对象进行设置修改。

cookie对象使用key-value(键值对)的形式保存用户状态,一个Cookie对象保存一个属性对,一个request或者response同时使用多个Cookie。因为Cookie类位于包javax.servlet.http.*下面,所以JSP中不需要import该类。


3.2 cookie的不可跨域名性

很多网站的服务器都会使用cookie,Cookie具有不可跨域名性根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。Cookie在客户端是由浏览器来管理的。浏览器能够保证Google只会操作Google的Cookie而不会操作Baidu的Cookie,从而保证用户的隐私安全。浏览器判断一个网站是否能操作另一个网站Cookie的依据是域名。


3.3 Unicode编码:中文字符

中英文的字符不同,中文属于Unicode字符,在内存中占4个字符;而英文属于ASCII字符,占2个字节。cookie中使用Unicode字符时,需要进行Unicode编码,否则会乱码。一般中文采用UTF-8编码即可。

cookie不仅可以使用ASCII字符和Unicode字符,还可以使用二进制数据。例如在Cookie中使用数字证书,提供安全度。使用二进制数据(如二进制图片)时也需要进行编码。


3.4 Cookie所有属性

cookie常用属性如下表

属性名描述String  name该cookie名称,一旦创建便不可变Object  value该cookie的值,如果是Unicode字符,则需要Unicode编码int maxAge该Cookie失效的时间,单位秒。如果为正数,则该Cookie在maxAge秒之后失效。如果为负数,该Cookie为临时Cookie,关闭浏览器即失效,浏览器也不会以任何形式保存该Cookie。如果为0,表示删除该Cookie。默认为–1boolean  secure该cookie是否使用安全协议进行传输。如HTTPS、SSL等,在网络上传输数据之前需先加密。默认为false。String  path该cookie的传输路径。如果设置为“/sessionWeb/”,则只有contextPath为“/sessionWeb”的程序可以访问该Cookie。如果设置为“/”,则本域名下contextPath都可以访问该Cookie。注意最后一个字符必须为“/”String  domain可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”String  comment该Cookie的用处说明。浏览器显示Cookie信息的时候显示该说明Int  version 该cookie的版本号

3.5 cookie的有效期

Cookie的maxAge决定着Cookie的有效期,单位为秒(Second)。Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。

如果maxAge属性为正数,则表示该Cookie会在maxAge秒之后自动失效。浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之前,登录网站时该Cookie仍然有效。下面代码中的Cookie信息将永远有效。


Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie

cookie.setMaxAge(Integer.MAX_VALUE);           // 设置生命周期为MAX_VALUE

response.addCookie(cookie);                    // 输出到客户端


失效的Cookie会被浏览器从Cookie文件或者内存中删除,例如:

Cookie cookie = new Cookie("username","helloweenvsfei");   // 新建Cookie

cookie.setMaxAge(0);                          // 设置生命周期为0,不能为负数

response.addCookie(cookie);                    // 必须执行这一句


response对象提供的Cookie操作方法只有一个添加操作add(Cookie cookie)。

要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。


注意:从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。


3.6  cookie的修改、删除


Cookie并不提供修改、删除操作。如果要修改某个Cookie,只需要新建一个同名的Cookie,添加到response中覆盖原来的Cookie。

如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。读者可以通过上例的程序进行验证,设置不同的属性。


注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、删除失败。


3.7  cookie的域名


cookie是不可夸域名的。正常情况下,同一个域名下的两个二级域名如www.baidu.com和image.baidu.com是不能交互使用cookie的,因为这两个域名并不严格相同。如果想要baidu.com下的所有二级域名都使用一个cookie,需对该cookie进行设置,例如:

Cookie  cookie = new Cookie("username","20160526");//新建cookie

cookie.setDomain(".baidu.com");//设置域名

cookie.setPath("/");//设置路径

cookie.setMaxAge(integer.Max_Value);//设置有效时间

response.addCookie(cookie);//输出到客户端

注意:domain参数必须以点(".")开始。另外,name相同但domain不同的两个Cookie是两个不同的Cookie。如果想要两个域名完全不同的网站共有Cookie,可以生成两个Cookie,domain属性分别为两个域名,输出到客户端。


3.8  cookie的安全性

HTTP协议不仅是无状态的,还是不安全的。可以设置cookie的secure属性为true。浏览器会在HTTPS和SSL等安全协议中传输此类cookie

cookie.setSecure(true);//设置安全性

提示:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。

4. cookie的缺点

  • cookie数量和长度的限制,每个domain最多只有20条cookie,每个cookie长度不能超过4K,否则会被截掉
  • 安全性问题。如果cookie被人拦截,那就可以取得所有session信息。即使加密也没用,因为并不需要知道cookie本身的意义,只需要按照原样转发就行了。
  • 有些状态不可能保存在客户端。例如:为了防止重复提交表单,我们需要在服务器端设计一个计数器,如果把计数器放在客户端将不起作用。


0 0