Cookie

Posted yusiming

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Cookie相关的知识,希望对你有一定的参考价值。

  Cookie是Http协议制定的内容,虽然Http协议是无状态的,但是我们可以通过使用Cookie来保存一些客户端的信息到服务器中,还可以使用Cookie来跟踪用户,典型的Cookie的使用-购物车,服务器可以跟踪用户在什么时间访问了哪些页面,以及访问这些页面的顺序,然后为用户维持一个购物品的列表,在结账时就可以一起付费了。

  在Http协议中,与Cookie有关的请求头有:

  Cookie:XXX

  与Cookie有关的响应头有:

  Set-Cookie:XXX

  需要注意的是Cookie是服务器发送给客户端的,客户端第一次发出请求时,是没有Cookie:XXX这个请求头的,因为服务器还未给客户端响应这个响应头Set-Cookie:XXX,在客户端第一次接收到服务器的响应时,响应头中就有可能有Set-Cookie:XXX这个响应头,然后客户端再次发出请求时,就会带上这个Cookie了,当然用户有权利不使用Cookie。

 

在Javaweb中使用Cookie

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        resp.addCookie(new Cookie("name", name));
    }
}

  在使用HttpServletResponse的addCookie方法往客户端设置Set-Cookie头时,需要方法传递一个Cookie对象,我们使用一个键值对,构造一个Cookie对象,

  上面的代码中,我们首先会获取客户端传递的name参数,然后将Cookie键值对中的值,发送到客户端,使用谷歌自带的抓包工具可以发现

  Set-Cookie:name=yu
  在响应头中,就有这么一个Cookie了,然后我们再次请求服务器,通过抓包发现
  Cookie:name=yu; Idea-c625d71e=5fc965e2-74b0-4eaa-a2b0-171e6a2a489d
  请求头中,存在上次服务器发送给客户端的Cookie头了,
 
public class AServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
            IOException {
        String name = null;
        Cookie[] cookies = request.getCookies();
        for (Cookie c : cookies) {
            if (c.getName().equals("name")) {
                name = c.getValue();
            }
        }
        response.getWriter().print("Hello" + name);
    }
}

  这段代码会将Cookie中名字是“name”的键对应的值输出到客户端,

Cookie的属性

  • Domian
    • Domian属性告诉浏览器应该将Cookie发送到那些域名中
  • Path
    • 进行一步限制在访问那些URL时应该带上Cookie
  • HttpOnly
    • 该属性限制了Cookie只能使用在浏览器的Http请求中,JS脚本对于这种Cookie,获取不到  
  • Secure
    • 浏览器将会只使用Https发送Cookie,该属性不需要有值  
  • Max-Age
    • 浏览器的过期时间,以秒为单位,当Max-Age为0时,浏览器将删除Cookie,当Max-Age < 0时,Cookie只保存在内存中,一旦浏览器进程退出,Cookie也就死亡了,当Max-Age > 0时,Cookie将被保存到硬盘中,
  • Expires
    • 定义了Cookie的绝对过期时间
  • Comment
    • 对Cookie的一些描述信息,用户可以浏览这些信息,了解Cookie的具体的用途  
 1 public class HelloServlet extends HttpServlet {
 2     @Override
 3     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 4         String name = req.getParameter("name");
 5         Cookie cookie = new Cookie("name", name);
 6         cookie.setMaxAge(60 * 60);
 7         cookie.setComment("save name");
 8         cookie.setHttpOnly(true);
 9         cookie.setSecure(true);
10         resp.addCookie(cookie);
11     }
12 }

 

 抓包到的内容:name=yu; Version=1; Comment="save name"; Max-Age=3600; Expires=Sun, 07-Oct-2018 15:23:30 GMT; Secure; HttpOnly
 
 还有一点需要注意,Cookie中不能存在中文,所以要想使用中文传递信息,先进行URL编码,一个例子:
 1 public class HelloServlet extends HttpServlet {
 2     @Override
 3     protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
 4         resp.addCookie(new Cookie("name", URLEncoder.encode("中文", "utf-8")));
 5     }
 6 }
 7 public class AServlet extends HttpServlet {
 8     protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,
 9             IOException {
10         String name = null;
11         Cookie[] cookies = request.getCookies();
12         for (Cookie c : cookies) {
13             if (c.getName().equals("name")) {
14                 name = URLDecoder.decode(c.getValue(), "utf-8");
15             }
16         }
17         System.out.println(name); // 中文
18     }
19 }

 

  HelloServlet 向客户端保存Cookie

  Set-Cookie:name=%E4%B8%AD%E6%96%87
  AServlet 解析收到的Cookie
  Cookie:name=%E4%B8%AD%E6%96%87; Idea-c625d71e=5fc965e2-74b0-4eaa-a2b0-171e6a2a489d
 
  这里使用到了两个类URLEncoder和URLDecoder来进行URL编码和解码

以上是关于Cookie的主要内容,如果未能解决你的问题,请参考以下文章

JavaScript单行代码,也就是代码片段

XSS:如何从 C# 中的字符串中删除 JS 片段?

Django cookie 横幅:window.wpcc 未定义

最详细的cookie和浏览隐私之间的关系

c#如何采集需要登录的页面

IE无法获得cookie,ie不支持cookie的解决办法,火狐支持