Cookie,Session的再次学习

      http是无状态的,它不对之前发生过的请求和响应状态进行管理。也就是说无法根据之前的状态进行本次的请求处理。为了解决这个技术引入了cookie技术。

       cookie会根据从服务端发送的响应报文的一个叫做Set-Cookie的首部字段信息,通知客户端保存Cookie。当下次客户端再往该服务器发送请求时,客户端会自动的 再请求报文加加Cookie值后再次发出去。

         服务器端发送客户端发送过来的Cookie后,会去检查究竟是从哪个客户端发送来的连接请求。

下面是针对结合Java中的服务Cookie实现类进行解释

 /**
     * 键
     */
    private final String name;
    /**
     * 值
     */
    private String value;
    /**
     * cookie的版本由cookie的定义者创建定义
     */
    private int version = 0;
    /**
     * 注释,用来描述cookie的用途
     */
    private String comment;
    /**
     * 可访问cookie的域名,解决跨域问题  比如 你想然让a.site.com与b.site.com共享cookie,则需要把这个属性设置为*.site.com
     */
    private String domain;
    /**
     * cookie的有效时间
     */
    private int maxAge = -1;
    /**
     * 可访问cookie的路径,默认为Path为产生cookie时的路径,此时cookie只能被该路径以及子路径下的页面访问;可以将Path设置为/,使cookie可以被网站下所有页面访问。
     */
    private String path;
    /**
     * 为true时只有HTTPS时才会生效,HTTP不会。默认为false
     */
    private boolean secure;
    /**
     * HTTP-Only 意思是告之浏览器该 cookie 绝不能通过 JavaScript 的 document.cookie 属性访问。目的时阻止通过 JavaScript 发起的跨站脚本攻击 (XSS) 窃取 cookie 的行为。
     */
    private boolean httpOnly;

cookie的主要内容包括:名字,值,过期时间,路径和域

 其中域可以指定某一个域比如.google.com,相当于总店招牌,比如宝洁公司,也可以指定一个域下的具体某台机器比如www.google.com或者froogle.google.com,可以用飘柔来做比。 

    路径就是跟在域名后面的URL路径,比如/或者/foo等等,可以用某飘柔专柜做比。路径与域合在一起就构成了cookie的作用范围。如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了。这种生命期为浏览器会话期的cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里,当然这种行为并不是规范规定的。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。 

    存储在硬盘上的cookie可以在不同的浏览器进程间共享,比如两个IE窗口。而对于保存在内存里的cookie,不同的浏览器有不同的处理方式。对于IE,在一个打开的窗口上按Ctrl-N(或者从文件菜单)打开的窗口可以与原窗口共享,而使用其他方式新开的IE进程则不能共享已经打开的窗口的内存cookie;对于Mozilla Firefox0.8,所有的进程和标签页都可以共享同样的cookie。一般来说是用javascript的window.open打开的窗口会与原窗口共享内存cookie。浏览器对于会话cookie的这种只认cookie不认人的处理方式经常给采用session机制的web应用程序开发者造成很大的困扰。 

使用代码的形式体现:

package com.gysoft.controller;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @Description
 * @Author DJZ-WWS
 * @Date 2019/5/24 13:55
 */
@RestController
public class CookieController {

    /**
     * 增加cookie
     *
     * @param response
     */
    @RequestMapping("/addCookie")
    public String addCookie(HttpServletResponse response) {
        Cookie cookie = new Cookie("foo", "bar");
        response.addCookie(cookie);
        return "添加成功";

    }

    /**
     * 读取cookie
     * @param request
     */
    @RequestMapping("/showCookie")
    public void showCookie(HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                String name = cookie.getName();
                String value = cookie.getValue();
                System.out.println("name:" + name + ",value:" + value);
            }
        } else {
            System.out.println("cookies is null");
        }
    }
    /**
     * 修改cookie
     */

    @RequestMapping("/editCookie")
    public void editCookie(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        String name = "foo";
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    cookie.setValue("new_bar");
                    System.out.println("修改的name为" + cookie.getName() + "修改后的值为:" + cookie.getValue());
                    response.addCookie(cookie);
                }
            }
        } else {
            System.out.println("cookies is null");
        }
    }
    /**
     * 删除Cookie
     *
     * @param request
     * @param response
     */
    @RequestMapping("/delCookie")
    public void delCookie(HttpServletRequest request, HttpServletResponse response) {
        Cookie[] cookies = request.getCookies();
        String name = "foo";
        if (cookies != null) {
            for (Cookie cookie : cookies) {
                if (cookie.getName().equals(name)) {
                    cookie.setMaxAge(0);
                    response.addCookie(cookie);
                    System.out.println("删除成功");
                    break;
                }
            }
        }
    }

}

不同的客户端可以携带不同的cookie,当我们访问服务端的时候会给这个cookie设置一个cookie 值,服务端将这个cookie的属性返回给客户端,客户端下次再访问的时候会利用相关的属性与服务端的进行比较,只有当他们一致的时候,服务端才会认为这是上次请求的客户端。

cookie的查看方式如下:

扫描二维码关注公众号,回复: 6427137 查看本文章

对于Session机制是一种服务器端的机制,可以将他理解为一个Map。他是一种基于cookie的技术。本质上session技术就是一种基于后端有别于数据库的临时存储数据的技术

工作原理:       

当程序需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里是否已包含了一个session标识 - 称为session id,如果已包含一个session id则说明以前已经为此客户端创建过session,服务器就按照session id把这个session检索出来使用(如果检索不到,可能会新建一个),如果客户端请求不包含session id,则为此客户端创建一个session并且生成一个与此session相关联的session id,session id的值应该是一个既不会重复,又不容易被找到规律以仿造的字符串,这个session id将被在本次响应中返回给客户端保存。 

          保存这个session id的方式可以采用cookie,这样在交互过程中浏览器可以自动的按照规则把这个标识发挥给服务器。一般这个cookie的名字都是类似于SEEESIONID,而。比如weblogic对于web应用程序生成的cookie,JSESSIONID=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764,它的名字就是JSESSIONID。 

         cookie被禁用了 怎么办?

由于cookie可以被人为的禁止,必须有其他机制以便在cookie被禁止时仍然能够把session id传递回服务器。经常被使用的一种技术叫做URL重写,就是把session id直接附加在URL路径的后面,附加方式也有两种,一种是作为URL路径的附加信息,表现形式为http://...../xxx;jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 
另一种是作为查询字符串附加在URL后面,表现形式为http://...../xxx?jsessionid=ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764 
这两种方式对于用户来说是没有区别的,只是服务器在解析的时候处理的方式不同,采用第一种方式也有利于把session id的信息和正常程序参数区分开来。 
为了在整个交互过程中始终保持状态,就必须在每个客户端可能请求的路径后面都包含这个session id。 
    另一种技术叫做表单隐藏字段。就是服务器会自动修改表单,添加一个隐藏字段,以便在表单提交时能够把session id传递回服务器。

参考:https://blog.csdn.net/crankz/article/details/80434190

          https://www.cnblogs.com/lonelydreamer/p/6169469.html

猜你喜欢

转载自blog.csdn.net/qq_35410620/article/details/90514838