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编码和解码
浙公网安备 33010602011771号