zoukankan      html  css  js  c++  java
  • 十二、cookie机制及特性和使用

      会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话。常用的会话跟踪技术是Cookie与Session。Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端记录信息确定用户身份。
    1.1 cookie机制:
        一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。而Web应用程序是使用HTTP协议传输数据的。HTTP协议是无状态的协议。一旦数据交换完毕,客户端与服务器端的连接就会关闭,再次交换数据需要建立新的连接。这就意味着服务器无法从连接上跟踪会话。即用户A购买了一件商品放入购物车内,当再次购买商品时服务器已经无法判断该购买行为是属于用户A的会话还是用户B的会话了。要跟踪该会话,必须引入一种机制。Cookie就是这样的一种机制。它可以弥补HTTP协议无状态的不足。在Session出现之前,基本上所有的网站都采用Cookie来跟踪会话。
        Cookie意为“甜饼”,是由W3C组织提出,最早由Netscape社区发展的一种机制。目前Cookie已经成为标准,所有的主流浏览器如IE、Netscape、Firefox、Opera等都支持Cookie。由于HTTP是一种无状态的协议,服务器单从网络连接上无从知道客户身份。怎么办呢?就给客户端们颁发一个通行证吧,每人一个,无论谁访问都必须携带自己通行证。这样服务器就能从通行证上确认客户身份了。这就是Cookie的工作原理。Cookie实际上是一小段的文本信息。客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。服务器还可以根据需要修改Cookie的内容。
        备注:Cookie功能需要浏览器的支持。如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。不同的浏览器采用不同的方式保存Cookie。IE浏览器会在“C:Documents and Settings你的用户名Cookies”文件夹下以文本文件形式保存,一个文本文件保存一个Cookie。
    1.2 cookie的特性:
        1.2.1) Cookie具有不可跨域名性:
           根据Cookie规范,浏览器访问Google只会携带Google的Cookie,而不会携带Baidu的Cookie。Google也只能操作Google的Cookie,而不能操作Baidu的Cookie。这是由Cookie的隐私安全机制决定的。
        隐私安全机制能够禁止网站非法获取其他网站的Cookie。
        注意:
            a.用户登录网站www.google.com(一级域名)之后会发现访问images.google.com(二级域名)时登录信息仍然有效,而普通的Cookie是做不到的。这是因为Google做了特殊处理。
            b.如果想所有helloweenvsfei.com名下的二级域名都可以使用该Cookie,需要设置Cookie的domain参数,例如:
                Cookie cookie = new Cookie("username","ceshi"); // 新建Cookie
                cookie.setDomain(".google.com");                   // 设置域名
                cookie.setPath("/");                            // 设置路径
                cookie.setMaxAge(Integer.MAX_VALUE);            // 设置有效期
                response.addCookie(cookie);                     // 输出到客户端
            c.开发人员可以修改本机C:WINDOWSsystem32driversetc下的hosts文件来配置多个临时域名,然后使用operateCookie.jsp程序来设置跨域名Cookie验证domain属性domain参数必须以点(".")开始。另外,name相同但domain不同的两个Cookie是两个不同的Cookie。如果想要两个域名完全不同的网站共有Cookie,可以生成两个Cookie,domain属性分别为两个域名,输出到客户端。
        1.2.2) 保存中文是需要转码为Unicode编码:
        中文与英文字符不同,中文属于Unicode字符,在内存中占4个字符,而英文属于ASCII字符,内存中只占2个字节。Cookie中使用Unicode字符时需要对Unicode字符进行编码,否则会乱码。
        备注:Cookie中保存中文只能编码。一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。
        1.2.3) 保存二进制图片需要使用BASE64编码:Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如在Cookie中使用数字证书,提供安全度。使用二进制数据时也需要进行编码。
        备注:本程序仅用于展示Cookie中可以存储二进制内容,并不实用。由于浏览器每次请求服务器都会携带Cookie,因此Cookie内容不宜过多,否则影响速度。Cookie的内容应该少而精。
        1.2.4)cookie有效期时间单位为秒:Cookie中通过getMaxAge()方法与setMaxAge(int maxAge)方法来读写maxAge属性。
        a.Cookie默认的maxAge值为–1  如果maxAge为0,则表示删除该Cookie。Cookie机制没有提供删除Cookie的方法,因此通过设置该Cookie即时失效实现删除Cookie的效果。失效的Cookie会被浏览器从Cookie文件或者内存中删除,    
        b.如果maxAge属性为正数  则表示该Cookie会在maxAge秒之后自动失效,浏览器会将maxAge为正数的Cookie持久化,即写到对应的Cookie文件中。无论客户关闭了浏览器还是电脑,只要还在maxAge秒之
          前,登录网站时该Cookie仍然有效。
        c.如果maxAge为负数  则表示该Cookie仅在本浏览器窗口以及本窗口打开的子窗口内有效,关闭窗口后该Cookie即失效。maxAge为负数的Cookie,为临时性Cookie,不会被持久化,不会被写到Cookie文
          件中。Cookie信息保存在浏览器内存中,因此关闭浏览器该Cookie就消失了。
        b.设置Cookie信息将永远有效
          Cookie cookie = new Cookie("username","ceshi");   // 新建Cookie
          cookie.setMaxAge(Integer.MAX_VALUE);               // 设置生命周期为MAX_VALUE
          response.addCookie(cookie);                        // 输出到客户端
        d.如何实现对cookie的修改:
          response对象提供的Cookie操作方法只有一个添加操作add(Cookie cookie)。要想修改Cookie只能使用一个同名的Cookie来覆盖原来的Cookie,达到修改的目的。删除时只需要把maxAge修改为0即可。
          备注:
            a.从客户端读取Cookie时,包括maxAge在内的其他属性都是不可读的,也不会被提交。浏览器提交Cookie时只会提交name与value属性。maxAge属性只被浏览器用来判断Cookie是否过期。
            b.修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie不予覆盖,导致修改、
            删除失败。
        1.2.5)允许进行Cookie访问的路径设置:
            domain属性决定运行访问Cookie的域名,而path属性决定允许访问Cookie的路径(ContextPath)。例如,如果只允许/session/下的程序使用Cookie,可以这么写:
            Cookie cookie = new Cookie("username","ceshi");      // 新建Cookie
            cookie.setPath("/session/");                               // 设置路径
            response.addCookie(cookie);                            // 输出到客户端
            备注:
                a.设置为“/”时允许所有路径使用Cookie。path属性需要使用符号“/”结尾。name相同但domain相同的两个Cookie也是两个不同的Cookie。
                b.页面只能获取它属于的Path的Cookie。例如/session/test/a.jsp不能获取到路径为/session/abc/的Cookie。使用时一定要注意。
        1.2.6)设置cookie的安全属性:
            HTTP协议不仅是无状态的,而且是不安全的。使用HTTP协议的数据不经过任何加密就直接在网络上传播,有被截获的可能。使用HTTP协议传输很机密的内容是一种隐患。如果不希望Cookie在HTTP等非安全协议中传输,可以设置Cookie的secure属性为true。浏览器只会在HTTPS和SSL等安全协议中传输此类Cookie。下面的代码设置secure属性为true:
            Cookie cookie = new Cookie("username", "ceshi");     // 新建Cookie
            cookie.setSecure(true);                                     // 设置安全属性
            response.addCookie(cookie);                              // 输出到客户端
            备注:secure属性并不能对Cookie内容加密,因而不能保证绝对的安全性。如果需要高安全性,需要在程序中对Cookie内容加密、解密,以防泄密。
        1.2.7)不支持跨域进行cookie窥探:
            客户端对cookie的设置: document.cookie = "CITY=" +cityCode+";domain=" + cookieDomain + ";path=/";
            备注:W3C组织早就意识到JavaScript对Cookie的读写所带来的安全隐患并加以防备了,W3C标准的浏览器会阻止JavaScript读写任何不属于自己网站的Cookie。换句话说,A网站的JavaScript程序
            读写B网站的Cookie不会有任何结果。
        1.2.8)cookie的键值对属性:
            Cookie对象使用key-value属性对的形式保存用户状态,一个Cookie对象保存一个属性对,一个request或者response同时使用多个Cookie。因为Cookie类位于包javax.servlet.http.*下面,所以JSP中不需要import该类。

    1.3 cookie信息的获取和赋值代码:

    <dependency>
        <groupId>javax.servlet</groupId>
        <artifactId>servlet-api</artifactId>
    </dependency>
    
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    // 一周 cookie的过期时间以秒为单位进行计算
    private static final int WEEK = 7 * 24 * 3600;
    
    /*
     *根据cookie的key获取名称
    */
    public static String getValue(HttpServletRequest request, String cookieName){
        if (StringUtils.isEmpty(cookieName)) {
            return null;
        }
        Cookie[] cookies = request.getCookies();
        if (cookies != null){
           for (int i = 0; i < cookies.length; i++) {
              if (cookieName.equalsIgnoreCase(cookies[i].getName())) {
                return cookies[i].getValue();
             }
           }
        }
        return null;
    }
    
    /*
     *设置cookie
     *maxAge
    */
    public static void setCookie(HttpServletResponse response,String cookieKey,String cookieValue,int maxAge){
        Cookie namecookie = new Cookie(cookieKey,cookieValue);
        namecookie.setMaxAge(maxAge);
        response.addCookie(namecookie);
    }
    View Code

    参看博文:https://www.cnblogs.com/ahang/p/5800064.html

    细水长流,打磨濡染,渐趋极致,才是一个人最好的状态。
  • 相关阅读:
    dom4j 解析 xml文件1
    java 简单的动态代理例子
    标识接口的作用 (转)
    JAVA servlet输出IE6下乱码
    java时间操作函数汇总
    IE支持getElementsByClassName方法
    女朋友问我 LB 是谁?
    人类高质量 Java 学习路线【一条龙版】
    程序员作图工具和技巧,你 get 了么?
    3 分钟了解 JSON Schema
  • 原文地址:https://www.cnblogs.com/jiarui-zjb/p/6406453.html
Copyright © 2011-2022 走看看