• [04] Cookie概念和基本使用



    1、Cookie是什么

    Cookie,中文名称为“小型文本文件”或“小甜饼”,指某些网站为了辨别用户身份而储存在用户本地终端上的数据(通常经过加密)。

    很多网站在你浏览后,会在你电脑中留下小小的档案,也就是我们说的Cookie,以便你再次浏览时,网站会读取它上次给你留下的Cookie资料,如果有的话,就可以根据内容来判断使用者,送出特定的网页内容。

    因为HTTP协议是无状态的,即服务器不知道用户上一次做了什么,这严重阻碍了交互式Web应用程序的实现。所以Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。

    Cookie的一个典型的应用是当登录一个网站时,网站往往会请求用户输入用户名和密码,并且用户可以勾选“下次自动登录”。如果勾选了,那么下次访问同一网站时,用户会发现没输入用户名和密码就已经登录了。这正是因为前一次登录时,服务器发送了包含登录凭据(用户名加密码的某种加密形式)的Cookie到用户的硬盘上。第二次登录时,(如果该Cookie尚未到期)浏览器会发送该Cookie,服务器验证凭据,于是不必输入用户名和密码就让用户登录了。

    “cookie”的图片搜索结果

    所以:
    • Cookie是保存在客户端的小文本
    • 保存位置分两种
      • (1)保存在客户端浏览器所占内存中,关闭浏览器后Cookie也消失
      • (2)保存在客户端PC机的硬盘上,设置有效时间,超期后失效

    但是要注意的是,Cookie既然能把小文本保存在客户端,并在服务器和客户端之间进行传输,那么意味着它也容易造成信息泄露,因此:
    • 不用Cookie保存对保密性要求高的信息,如银行卡密码等
    • 不用Cookie实现某些必要功能,防止Cookie删除后功能出现错误
    • 可以通过浏览器设置阻止Cookie,或手工清除Cookie
    • Cookie放在请求头Header里,而不是主体Body中,所以GET或POST方式的请求都可以发送Cookie

    另外,Cookie还有一些缺陷
    • Cookie会被附加在每个HTTP请求中,所以无形中增加了流量
    • 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题(除非用HTTPS)
    • Cookie的大小限制在4KB左右。对于复杂的存储需求来说是不够用的

    如果你想看到自己的Cookie,也打开某个网站,在控制台调用JS代码: javascript:alert("Cookie:"+document.cookie) 或 javascript:document.write(document.cookie) 

    2、Java中的Cookie类

    在Servlet API中,存在Cookie类,可以使用new关键字进行创建:
    Cookie cookie = new Cookie("username", "zhangsan"); 

    可以看到,Cookie对象是保存一对键值对,都是字符串形式

    Cookie类定义了一系列的方法,摘要部分如下:
    类型    方法名    说明    
    void     setMaxAge(int expiry)    设置Cookie有效期,以秒为单位,保存在硬盘上或内存中
    • 正数:保存到客户端硬盘上,一定时间有效
    • 负数:浏览器关闭时Cookie被删除
    • 零:Cookie被删除
    void    setValue(String value)    Cookie创建后,对Cookie进行赋值    
    String    getName()    获取Cookie的名称    
    String     getValue()    获取Cookie的值    
    String     getMaxAge()    获取Cookie的有效时间,以秒为单位

    保存和获取Cookie
    • 把Cookie保存到客户端  response.addCookie(Cookie cookie)
    • 获取请求中的Cookies request.getCookies()

    Cookie要保存到客户端,凡是写到客户端的方法,基本都是在响应中,HttpServletResponse提供了方法,把Cookie保存到客户端;而再次访问与保存Cookie相同域名的网站时,HTTP协议将把有效时间内的Cookie都发送到服务器,容器将Cookie封装到请求中,HttpServletRequest提供了获取Cookie对象数组的方法。

    3、一个示例带你看Cookie

    上面单纯文字的说明太过干瘪,那么就来一个生动鲜活的例子:

    写登陆页面展示如下:
    <%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>登陆页面</title>
    </head>
    <body>
    <%
    String username = null;
    String password = null;
    
    //获取请求中的所有cookie对象
    Cookie[] cookies = request.getCookies();
    
    //只要存在Cookie,就查找是否有用户名和密码
    if(cookies != null) {
    	for(Cookie cookiesTemp : cookies) {
    		if(cookiesTemp.getName().equals("username")) {
    			username = cookiesTemp.getValue();
    		}
    		if(cookiesTemp.getName().equals("password")) {
    			password = cookiesTemp.getValue();
    		}
    	}
    }
    
    if(username != null && password != null) {
    	request.getRequestDispatcher("LoginServlet?username=" + username + "&pwd=" + password).forward(request, response);
    }
    %>
    
    <form name="form1" action="LoginServlet" method="post">
    用户名:<input type="text" id="username" name="username"><br>
    密码:<input type="password" id="pwd" name="pwd"><br>
    <select id="timelength" name="timelength">
    	<option value="0" selected>每次都需要登陆</option>
    	<option value="3">3天内免登陆</option>
    	<option value="7">7天内免登陆</option>
    </select><br>
    <input type="submit" name="submit" value="登陆">
    </form>
    
    </body>
    </html>

    写后台Servlet代码如下:
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html; charset = utf-8");
        //获取用户名、密码
        String username = request.getParameter("username");
        String password = request.getParameter("pwd");
        
        //获得JSP页面的时间信息
        String timelength = request.getParameter("timelength");
        int days = 0;
        
        //类型转换
        if(timelength != null) {
            days = Integer.parseInt(timelength);
        }
        
        //只要天数不为0,则创建cookie,设置有效时间,存到客户端
        if(days != 0) {
            Cookie usernameCookie = new Cookie("username", username);
            Cookie passwordCookie = new Cookie("password", password);
            usernameCookie.setMaxAge(days * 24 * 3600);
            passwordCookie.setMaxAge(days * 24 * 3600);
            response.addCookie(usernameCookie);
            response.addCookie(passwordCookie);	
        }
        
        //跳转到home.jsp
        request.getRequestDispatcher("home.jsp").forward(request, response);
    }

    该示例中,输入账户密码登陆后,Servlet中最后会调用response.addCookie方法,将账号密码存到客户端的硬盘上。

    我们就到硬盘里去翻一翻,在这之前要说明的是:
    • 不同浏览器的Cookie存放位置不同
    • 不同浏览器的Cookie存放文件格式不同,IE采用明文的文本文件,Safari采用二进制文件,Chrome和Firefox采用的是Sqlite数据库文件格式

    3.1 IE

    为了方便展示,我们用IE浏览器登陆一次,然后可以在浏览器设置中,找到存放Cookie文件的位置:
     
    可以看到,除了刚才登陆的localhost,也还有平时登陆其他网站留下的Cookie,我们看刚才登陆的localhost的Cookie就行了:

    可见,确实把我们的账号和密码放到了Cookie中,并发送到了客户端的硬盘里:
     

    3.2 Chrome

    Chrome因为文件格式问题,直接在硬盘上打开实际上你看到的基本都是乱码:
     
     
    但索性我们还是可以直接在浏览器中看到的:
     
     
     

    4、Cookie的格式

    我们已经知道了Cookie是个小文本,而且也基本是按照key/value的方式存储,所以也才有了封装的Cookie对象用来保存一对键值对。

    Cookie的内容当然不止我们定义的那对key/value,实际上它是有一定格式的。Cookie的标准格式定义在不同浏览器中实现,在历史上也有差异。下面是常用的标准格式,或者说属性:
    • name  用户可定义的key
    • value  用户可定义的value
    • comment  用来提供注释说明
    • path  指定Cookie作用路径,和Domain配合限制Cookie的作用范围
    • domain  指定作用域
    • max-age  指定Cookie失效时间
    • secure  用来远程发送Cookie时告知浏览器数据已加密,只能HTTPS连接被发送
    • httponly  本地JavaScript无法读取Cookie信息

    这里再说明一下path和domain,假设写Cookie的程序的访问路径是 http://localhost:8080/JavaWeb/servlet/CookieDemo
    • localhost就是域名
    • /JavaWeb/servlet就是当前Cookie的path

    假设现浏览器存的cookie的路径是/JavaWeb/servlet/,则:
    • 访问的地址是:http://localhost:8080/JavaWeb/servlet/CookieDemo   则带该cookie
    • 访问的地址是:http://localhost:8080/JavaWeb/CookieDemo   则不带该cookie

    也就是说,Cookie有个不可跨域名性,就像访问Google只会带上Google的Cookie,而不会带上Baidu的Cookie。

    如下示例图,访问淘宝网时携带的Cookie:
     

    5、最后

    因为Cookie实现自动登录涉及到用户信息安全的问题,实际上真正的自动登录不会像上面这么简单粗暴的,从我们查看Cookie就可以知道,账号密码都可以赤裸裸地看到,这显然是不行的。

    但是这里不做展开,留下部分参考,以便未来学习:


  • 相关阅读:
    转:UFLDL_Tutorial 笔记(deep learning绝佳的入门资料 )
    转:使用RNN解决NLP中序列标注问题的通用优化思路
    CTR预估中GBDT与LR融合方案
    ZOJ1157, POJ1087,UVA 753 A Plug for UNIX (最大流)
    Gentoo:startx出现Failed to load module问题
    HTTP请求和响应2:方法(Method)
    SharePoint 2013 表单认证使用ASP.Net配置工具加入用户
    理解支持向量机(四)LibSVM工具包的使用
    LeetCode 14: Longest Common Prefix
    精通Hibernate——域对象之间的关系
  • 原文地址:https://www.cnblogs.com/deng-cc/p/7462876.html
Copyright © 2020-2023  润新知