Cookie与Session的工作原理解析

cookie和session大家一定不会陌生,至少大家都会知道cookie与session最简单的区别:cookie是存在客户端即浏览器端的,session是存储在服务器端的。作者最近在实习当中使用到了session和cookie,有一点小感触,记录下来与大家一起学习。

1.cookie的作用

先给大家解释一下,HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力,通俗一点讲就是,你两次访问同一个网站,你登录之后,跳转其他页面,服务器是无法确认你是否已经登录。于是,两种用于保持HTTP连接状态的技术就应运而生了,一个是 Cookie,而另一个则是 Session,分别应用于客户端与服务器。

2.cookie与session的工作原理

接下来,就是我们今天重点分享的知识了,cookie和session是同构怎样的一种交互来记录状态的呢?为了简单说明,我以用户登录为例。

首先,就是在浏览器端,用户输入账号、密码、验证码,点击登录时,浏览器会向服务器发送请求,此时,浏览器会自动将之前保存的cookie(如果存在的话)放入header中

之后浏览器通过一系列的逻辑验证,将用户信息存入session中。接下来两张图,第一张是我服务器端日志打印出来的sessionId,第二张为我浏览器端向服务端验证是否为登录状态发送的header信息:


可以看到,服务器端的sessionID与存储在客户端cookie中的sessionID值是相同的。

接下来,我们就讲一下工作原理:

首先,在客户端,我们有两种方法来设置header中cookie的信息:

1)通过浏览器,自动将cookie填充到header中,这种方法我们不进行叙述。

2)通过ajax,设置header属性:

$.ajax({
    url: "",
    data: {},
    type: "GET",
    beforeSend: function(xhr){xhr.setRequestHeader('cookie', sessionId);},//这里设置cookie
    success: function() {}
});

其次在服务器端,通过request对象获取session,这里也分两种情况,如果请求的是传统的servlet Web请求方式,他是有HttpServletRequest 类型的参数的,可以直接获取,若是通过接口调用,比如webservice接口,可以在web.xml中配置listener,监听来自客户端的请求,代码如下:

<listener>
    <listener-class>
            org.springframework.web.context.request.RequestContextListener
    </listener-class>
</listener>
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
HttpServletRequest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
HttpSession session = request.getSession();
而servlet访问就简单的多了,
HttpSession session = request.getSession();
最后,浏览器需要将sessionID返回给客户端,同样式分为两种情况:

1)servlet访问

其中HttpServletResponse 对象有两个方法setHeader和addCookie。

setHeader可以指定特定名称的头信息的值,addDateheader,addIntHeader,setDateHeader,setIntHeader可以加入或理性特定时间或整数型头信息。;
addCookie方法可以在Web服务器响应中加入Cookie对象,这个对象将被浏览器所保存。Cookie机制也被用来维护会话状态。 

Cookie c1 = new Cookie("sessionId",session.getId());
response.addCookie(c1);
这种方式是最便捷的,因为在浏览器端不需要你做任何处理。

2)WebService接口访问

既然有对应的获取request的方法,自然我们也要向浏览器返回sessionID,不过,实例化一个对应request对象的response,可能太过麻烦(作者自己也不会,下次看了源码在和大家分享),我使用通过接口返回了一个JSON格式的数据,并在服务器端将sessionID存入cookie中:

LoginSessionId loginSessionId = new LoginSessionId();
loginSessionId.setSessionId(session.getId());
return loginSessionId

loginSessionId是我使用的接口定义的返回类型,在返回时会自动转为JSON格式的数据

           $.ajax({
		type: "POST",
		url: addUrl+"?"+result,
		dataType: "json",
		contentType:"application/json",
		data:JSON.stringify(loginUserPojo),
		beforeSend: function(jqXHR){
			ShowLoading();
		},
		complete : function(jqXHR, textStatus){
			HideLoading();
		},
		success : function(data){
				
				localStorage.setItem(localURL_NoPath+"GCsessionId",data.sessionId);
				SetCookie(localURL_NoPath+"GCsessionId",data.sessionId);
					
		},

在浏览器端保存了对应的cookie后,之后的操作浏览器就可以帮我们完成了,我们只需要在服务器端拦截请求,通过request获取session就够了。

发布了27 篇原创文章 · 获赞 212 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_34666857/article/details/76710363