Cookie原理、Set-Cookie常用字段、应用

一、保持网络状态

  • HTTP是无状态协议,它不对之前发生的请求和响应的状态进行管理。也就是说,无法根据之前的状态进行本次的请求处理。
    比如登录后页面跳转为了保持登录状态可以用两种方式记录状态①每次跳转都要再次登录(无法接受)②在请求报文中附加参数来管理登录状态。(cookie由此而来)

二、cookie的状态管理

1576215292(1)

  • 从图可以看出,cookie是服务端生成,保存在客户端。
    1576202805(1)

当服务端收到浏览器发送的用户ID时,就知道(通过读取cookie中字段,来进行身份鉴别)此次请求来自一个已经登录的用户。在以上的交互过程中,保持在客户端的用户ID就被称为cookie。

三、字段

  • 请求头对应Cookie字段、响应头对应Set-Cookie字段

1576202237(1)
Set-Cookie:value [ ;expires=date][ ;domain=domain][ ;path=path][ ;secure]

value:一般是键值对

expires:表示会在xxx时间之后失效(浏览器不会再发送给服务器),对于失效cookie浏览器会清空(也不是显式删除,是别的cookie覆盖此cookie,从而实现旧cookie删除)

public void setMaxAge(int expiry)
Sets the maximum age in seconds for this Cookie.

//正数:会保存到cookie文件中,不论关闭浏览器或关闭电脑,直到时间到才会过期。
A positive value indicates that the cookie will expire after that many seconds have passed.
Note that the value is the maximum age when the cookie will expire, not the cookie's current age.

//负数(会话cookie),表示此cookie只是存储在浏览器内存里,只要关闭浏览器,此cookie就会消失。
maxAge默认值为-1。
A negative value means that the cookie is not stored persistently and will be deleted when the Web browser exits. 
A zero value causes the cookie to be deleted.

Parameters:
expiry - an integer specifying the maximum age of the cookie in seconds; if negative, means the cookie is not stored; if zero, deletes the cookie

domain:默认是主机名,只有对相同的主机名发出请求时发出此cookie。像Yahoo,有很多格式是name.yahoo.com(比如my.yahoo.com,finance.yahoo.com),一般是有其中一个网站的cookie,其他的网站均能访问,通过设置.yahoo.com(从而实现了子域访问)。浏览器尾部比对规则:将.yahoo.com与发出请求的host尾部进行比对。若匹配,则发送相应的cookie。若不设置,则是yahoo.com,其子域是不能访问的。
一般所说的不可跨域是指二级域名层次,比如.yahoo.com和.baidu.com。
有"dot",是历史原因,若后端代码不写dot,response时会加上。

------------默认,不可访问子域----------------------
// at site.com
document.cookie = "user=John"

// at forum.site.com
alert(document.cookie); // no user

------------设置,可访问子域----------------------
// at site.com
// make the cookie accessible on any subdomain *.site.com:
document.cookie = "user=John; domain=site.com"

// later

// at forum.site.com
alert(document.cookie); // has cookie user=John

path:若path=/admin,则页面/admin和/admin/sth是可以访问的(当前及子域),而/home、/adminpage是不能访问的;通常设置为path=/,让网站的所有页面均可以访问。若不设置,默认是 /项目名称/当前路径的上一层地址
比如http://localhost/day07_03/AServlet时,服务器响应了一个Cookie,那么这个Cookie的默认路径就是/day07_03/。

假设你的浏览器当前已经有了两个Cookie:

c1:name=id; value=itcast; path=/day07_03/
c2:name=name; value=qdmmy6; path=/day07_03/servlet/
 
当访问http://localhost/day07_03/*时,请求头中会包含c1,而不会包含c2。
当访问http://localhost/day07_03/servlet/*时,请求头中会包含c1和c2。
也就是说,在访问子路径时,会包含其父路径的Cookie,而在访问父路径时,不包含子路径的Cookie。

在这里插入图片描述
如果你想在BServlet中设置的Cookie,在客户端访问AServlet时也包含在请求头中,那么就需要设置BServlet中的Cookie的path:

c2.setPath(“/day07_03/”):硬编码;
c2.setPath(request.getContextpath() + “/”):活编码。

这样就可以设置Cookie的路径,保存在访问AServlet时,也会包含BServlet中添加的Cookie。

注意:只有domain一致,才会比对path
domain+path组成了URL。

secure:默认情况下,在http://site.com下设置cookie,在https://site.com也是可以使用的,反之亦然。也就是说cookie是domain-based,与协议无关。对于敏感内容不能通过未加密的http发送的,则应该设置secure,从而在https://site.com发送cookie,在http://site.com不发送cookie

  • 当不写expires时,其有效期就是浏览器内存,浏览器关闭则消失。
  • 存储在硬盘中cookie可以在不同的浏览器间共享,比如火狐、IE;而基于内存的,只在当前浏览器有效,换相同的浏览器也不行
  • 当cookie从服务端发送给客户端后,服务端不存在显式删除cookie的方法。但是当它过期了,用户重新登录,则会覆盖之前的cookie。从而对客户端的cookie实质性的删除。

四、Cookie的用途

  • 记录用户登录状态
  • 购物车
    1576204837(1)
  • 将cookie保存在客户端,容易随着用户的操作导致cookie丢失或者被窃取。因此不安全!
    因此, Cookie中适合存储对安全性要求不高,但是需要长时间保存的数据。

五、Cookie代码(保存登录信息)

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <title>My JSP 'login.jsp' starting page</title>
</head>

<body>

This is my JSP page. <br>
<form action="login" method="post" >
  username:<input type="text" name="username" id="un"><br>
  password:<input type="password" name="pwd" id="pw"><br>
    <input type="submit" value="sign in"/>
</form>
</body>
</html>
public class HelloWorld extends HttpServlet {
 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws 
 ServletException, IOException {
        String username = req.getParameter("username");
        System.out.println(username);
            Cookie un_cookie = new Cookie("username", username);
            un_cookie.setMaxAge(100);
            //un_cookie.setPath("/Cookie_learn_war_exploded");
//虽然只是在这里添加了cookie,但根据path+domain,只要符合要求的jsp页面均可以用此cookie
            resp.addCookie(un_cookie);
            resp.sendRedirect("success.jsp");
    }
success.jsp:
<%
  String path = request.getContextPath();
  String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <base href="<%=basePath%>">
  <title>My JSP 'login.jsp' starting page</title>

</head>

<body>
<%
  String userName = null;
  Cookie[] cookies = request.getCookies();
  if(cookies !=null) {
    for (Cookie cookie : cookies) {
      if (cookie.getName().equals("username"))
        userName = cookie.getValue();
    }
  }
%>

<%= userName %>  welcome!
</body>
</html>
   <servlet>
        <servlet-name>HelloWorld</servlet-name>
        <servlet-class>HelloWorld</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>HelloWorld</servlet-name>
        <url-pattern>/login</url-pattern>
    </servlet-mapping>

六、Cookie的限制

  1. Cookie数量和长度的限制。每个domain最多只能有20条cookie(取决于浏览器),若达到上限,则浏览器随机删除cookie;每个cookie长度不能超过4KB,否则会被截掉;浏览器最多300个cookie。
  2. 安全性问题。如果cookie被人拦截了,那人就可以取得所有的cookie信息。即使加密也与事无补,因为拦截者并不需要知道cookie的意义,他只要原样转发cookie就可以达到目的了。
    (cookie是服务端给客户端的用户标识,而不是进行身份认证)

参考:
https://humanwhocodes.com/blog/2009/05/05/http-cookies-explained/
https://flaviocopes.com/cookies/#set-a-cookie-path
https://blog.csdn.net/weixin_41547486/article/details/81294238

  • 15
    点赞
  • 65
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值