Cookie会话机制

一.What is Cookie

    我们在浏览器中,经常涉及到数据的交换,比如你登录邮箱,登录一个页面。我们经常会在此时设置30天内记住我,或者自动登录选项。那么它们是怎么记录信息的呢,答案就是今天的主角cookie了,Cookie是由HTTP服务器设置的,保存在浏览器中,但HTTP协议是一种无状态协议,在数据交换完毕后,服务器端和客户端的链接就会关闭,每次交换数据都需要建立新的链接就像我们去超市买东西,没有积分卡的情况下,我们买完东西之后,超市没有我们的任何消费信息,但我们办了积分卡之后,超市就有了我们的消费信息。cookie就像是积分卡,可以保存积分,商品就是我们的信息,超市的系统就像服务器后台,http协议就是交易的过程。

Cookie的作用是储存在用户本地终端上的数据,也可以叫做浏览器缓存。

二.Cookie机制

    Cookie信息则存放在HTTP请求头(Request Header)里。有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。

    如果你把Cookies看成为http协议的一个扩展的话,理解起来就容易的多了,其实本质上cookies就是http的一个扩展。有两个http头部是专门负责设置以及发送cookie的,它们分别是Set-Cookie以及Cookie。当服务器返回给客户端一个http响应信息时,其中如果包含Set-Cookie这个头部时,意思就是指示客户端建立一个cookie,并且在后续的http请求中自动发送这个cookie到服务器端,直到这个cookie过期。一个cookie的设置以及发送过程分为以下四步:

客户端发送一个http请求到服务器端 服务器端发送一个http响应到客户端,其中包含Set-Cookie头部 客户端发送一个http请求到服务器端,其中包含Cookie头部 服务器端发送一个http响应到客户端。

这个通讯过程也可以用以下下示意图来描述:

在客户端的第二次请求中包含的Cookie头部中,提供给了服务器端可以用来唯一标识客户端身份的信息。这时,服务器端也就可以判断客户端是否启用了cookies。

三.Cookie的原理

    由于HTTP是一种无状态的协议,服务器脚本向浏览器发送一组 Cookie。例如:姓名、年龄或识别号码等。浏览器将这些信息存储在本地计算机上,以备将来使用。当下一次浏览器向 Web 服务器发送任何请求时,浏览器会把这些 Cookie 信息发送到服务器,服务器将使用这些信息来识别用户。这就是Cookie的工作原理

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

    查看某个网站颁发的Cookie很简单。在浏览器地址栏输入javascript:alert (document. cookie)就可以了(需要有网才能查看)。JavaScript脚本会弹出一个对话框显示本网站颁发的所有Cookie的内容。Cookie的信息是可以加密的,比如baidu等

注意:Cookie功能需要浏览器的支持。如果浏览器不支持Cookie(如大部分手机中的浏览器)或者把Cookie禁用了,Cookie功能就会失效。不同的浏览器采用不同的方式保存Cookie。IE浏览器会在“C:\Documents and Settings\你的用户名\Cookies”文件夹下以文本文件形式保存,一个文本文件保存一个Cookie。

四.Cookie的分类

cookie分为会话cookie和持久cookie,会话cookie是指在在不设定它的生命周期expires时的状态,前面说了,浏览器的开启到关闭就是一次会话,当关闭浏览器时,会话cookie就会跟随浏览器而销毁。当关闭一个页面时,不影响会话cookie的销毁。会话cookie就像我们没有办理积分卡时,单一的买卖过程,离开之后,信息则销毁。如果cookie的生存时间是整个会话期间的话,那么浏览器会将cookie保存在内存中,浏览器关闭时就会自动清除这个cookie

持久cookie则是设定了它的生命周期expires,此时,cookie像商品一样,有个保质期,关闭浏览器之后,它不会销毁,直到设定的过期时间。对于持久cookie,可以在同一个浏览器中传递数据,比如,你在打开一个淘宝页面登陆后,你在点开一个商品页面,依然是登录状态,即便你关闭了浏览器,再次开启浏览器,依然会是登录状态。这就是因为cookie自动将数据传送到服务器端,在反馈回来的结果。持久cookie就像是我们办理了一张积分卡,即便离开,信息一直保留,直到时间到期,信息销毁。另外一种情况就是保存在客户端的硬盘中,浏览器关闭的话,该cookie也不会被清除,下次打开浏览器访问对应网站时,这个cookie就会自动再次发送到服务器端

五.Cookie和Session的区别

    在程序中,会话跟踪是很重要的事情。理论上,一个用户的所有请求操作都应该属于同一个会话,而另一个用户的所有请求操作则应该属于另一个会话,二者不能混淆。

1、Cookie机制是在客户端保持状态的方案,又叫会话跟踪机制。Session机制采用的是在服务器端保持状态的方案。

两者都是打开一次浏览器到关闭浏览器算是一次会话结束

2、Cookie数据存放在客户的浏览器上,Session数据放在服务器上。

3、Cookie不是很安全,别人可以分析存放在本地的Cookie并进行Cookie欺骗,考虑到安全应当使用Session。

4、Session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能。考虑到减轻服务器性能方面,应当使用Cookie。

注意:为什么要用到会话机制?

    HTTP协议是一种无状态协议,在数据交换完毕后,服务器端和客户端的链接就会关闭,每次交换数据都需要建立新的链接。此时,服务器无法从链接上跟踪会话。cookie可以跟踪会话,弥补HTTP无状态协议的不足。

六.Cookie的属性

JavaScript Cookie教程

Servlet Cookie教程

Servlet Cookie常用的API:

(1)getName();获得名字;
(2)getValue();获得对应的值;
(3)setDomain(String domain);设置cookie的有效域名;
(4)setPath(String path);设置cookie的有效路径;
(5)setMaxAge(int maxAge);设置cookie的有效时间。

七.Cookie的使用

Cookie可以设置在客户端和服务端。这里练习用服务端Demo:

商品的浏览历史记录

步骤:
点击某个商品,将商品ID传递给一个Servlet
在Servlet中判断是否是第一次浏览商品
如果是第一次:将商品ID存入到cookie中
如果不是,判断商品是否被浏览过,如果浏览过,就 删除对应的cookie,添加到首尾,没有就判断是否达到浏览商品显示的最大值,
如果没有就直接添加到第一个,如果达到了就删除最后一个,再添加都首位

public class ServletDemo2 extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //接收用户点击商品传递过来的id
        String id = request.getParameter("id");
        //获得所有的cookie信息
        Cookie[] cookies = request.getCookies();
        //判断有没有浏览过这个商品
        Cookie cookie = CookieUtils.findCookie(cookies,id);
        //用户是第一次浏览
        if(cookie == null) {
            //创建cookie对象
            Cookie c = new Cookie("history", id);
            //设置一个小时的销毁
            cookie.setMaxAge(60*60);
            //发送cookie
            response.addCookie(c);
            //用户不是第一次浏览
        }else {
            //得打cookie的值
            String value = cookie.getValue();
            //切掉在拼接cookie时的,号
            String[] ids = value.split(",");
            //将数组转换成集合
            List<String> aslist = Arrays.asList(ids);
            //将list转换成linkedlist
            LinkedList<String> list = new LinkedList<>(aslist);
            //如果用户之前浏览过这个商品
            if(list.contains(id)) {
                //删除对应的
                list.remove(id);
                list.addFirst(id);
                //没有浏览过
            }else {
                //判断是否达到最大值
                if(list.size() < 3) {
                    //直接添加到第一个
                    list.addFirst(id);
                    //达到最大值
                }else {
                    //删除最后一个
                    list.removeLast();
                    list.addFirst(id);
                }
            }
            //创建拼接的StringBuffer
            StringBuffer sb = new StringBuffer();
            for(String s:list) {
                sb.append(s).append(",");
            }
            //去掉最后一个,号
            String idValue = sb.toString().substring(0,sb.length()-1);
            //保存到cookie中
            Cookie c = new Cookie("history", idValue);
            //发送
            response.addCookie(c);
        }
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}
class CookieUtils {

    public static Cookie findCookie(Cookie[] cookies,String name){
        if(cookies == null){
            return null;
        }else{
            for(Cookie cookie:cookies){
                if(name.equals(cookie.getName())){
                    return cookie;
                }
            }
            
            return null;
        }
    }
}

清空浏览历史记录

点击清空浏览历史记录的超链接,
跳转到servlet
得到指定保存浏览历史记录的cookie,
设置保存时间为0
重定向到商品显示页面

public class Demo3Servlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //获得所有的cookie
        Cookie[] cookies = request.getCookies();
        //遍历cookies,拿到保存浏览历史记录的cookie
        for (Cookie cookie : cookies) {
            if(cookie.getName().equals("history")) {
                //设置保存时间为0
                cookie.setMaxAge(0);
            }
        }
        //重定向
        response.sendRedirect(request.getContextPath()+"/list.jsp");
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }

}

猜你喜欢

转载自blog.csdn.net/wang_snake/article/details/81296800