同一web应用多次进入不同页面时,为了避免多次登陆操作,就有了cookie,用户把少量的信息以键值对的方式存储到自己的电脑上,可以随意的修改,这样很不安全。就产生了一个新的存储会话机制:session,session也是一种服务区存储数据的方式,它存在服务器的/tmp 目录下(本地服务器存储地址为tomcat的/tep目录下),session的全部机制是基于这个session_id,它用来区分哪几次请求是一个人发出的。为什么要这样呢?因为HTTP是无状态无关联的,一个页面可能会被成百上千人访问,而且每个人的用户名是不一样的,那么服务器如何区分这次是小王访问的,那次是小明访问的呢?所以就有了找个唯一的session_id 来绑定一个用户。一个用户在一次会话上就是一个session_id,这样成千上万的人访问,服务器也能区分到底是谁在访问了。通常实现登陆是通过cookie存储一个session_id,然后具体的数据保存在session中,如果用户已登陆,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_id在session库中获取用户的session数据,就能知道该用户到底是谁,以及之前保存的一些状态。
① cookie是存储在客户端的,session是存储在服务端的,所以session的安全性高于coookie。
② 获取的session里的信息是通过存放在会话cookie里的sessionId获取的。
③ 因为session是存放在服务器里的,所以session里的东西不断增加会增加服务器的负担,我们会把一些重要的东西放在session里,不太重要的放在cookie里。
④ cookie分为两大类,一个是会话cookie和持久化cookie,他们的生命周期和浏览器是一致的,浏览器关了会话cookie也就消失了,所以session也就消失了,session丢失的情况为服务器关闭或者session过期(默认三十秒)。
① 客户首次访问服务器的一个页面时,服务器就会为该用户分配一个session对象,同时为这个session指定唯一的ID,并且将该ID发送到客户端并写入到cookie中,使得客户端与服务器的session建立一一对应的关系;
② 当客户端继续访问服务器端的其它资源时,服务器不再为该客户分配新的session对象,直到客户端浏览器关闭、超时或调用session的invalidate()方法使其失效,客户端与服务器的会话结束。
③ 当客户重新打开浏览器访问网站时,服务器会重新为客户分配一个session对象,并重新分配sessionID。
用途
注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie而不会覆盖之前的Cookie,从而导致修改、删除失败。
//创建一个cookie并设置过期时间
Cookie cookie = new Cookie("key","value");
cookie.setMaxAge(60*60*24);//设置过期时间,单位为秒
cookie.setValue("newValue");//给当前cookie的value重新赋值
cookie.setComment("这个cookie是用来测试玩的");//对当前cookie进行描述的信息
cookie.Domain(".baidu.com");//这个cookie只能在域名为baidu.com的网站内使用,必须符合pattem域名正则规范(不能跨域!!)
cookie.setHttpOnly(true);//设置为true之后,只能通过http访问该cookie,js无法访问,还可以防止xss读取cookie
cookie.setPath("/");//设置cookie的使用路径,后面紧跟着详解。如果设置为"/shop/",则只有url为"/shop/"的程序可以访问,如果设置为"/",则该域名(服务器)下的所有url都可以访问该cookie。注意最后一个字符必须为"/"
cookie.setSecure(true);//是否使用安全传输协议。为true时,只有当是https请求连接时cookie才会发送给服务器端,而http时不会,但是服务端还是可以发送给浏览器端的
//保存到客户端
HttpServletResponse response;//从浏览器获取到的response,在接口方法的括号里面写这一句话
//HttpServletResponse response = ServletActionContext.getResponse();//ssh项目得到response
response.addCookie(cookie);
//HttpServletRequest request;//从浏览器获取到的response,在接口方法的括号里面写这一句话
HttpServletRequest request = ServletActionContext.getRequest();//ssh项目得到request
Cookie[] cookies = request.getCookies();//得到该客户端的全部cookie
String username=null;
String pwd=null;
for(Cookie c :cookies){
if("username".equals(c.getName())&&"pwd".equals(c.getName())){
username=c.getValue();
pwd=c.getValue();
break;
}
}
HttpServletRequest request = ServletActionContext.getRequest();//ssh项目得到request
HttpServletResponse response = ServletActionContext.getResponse();//ssh项目得到response
HttpSession session = request.getSession();
session.setAttribute("key","value");//向session中添加一个键值对,如果这个键是会话范围内存在,则更改该value的值。
session.getAttribute("key");//返回value,如果没有这个键值对则返回null
session.removeAttribute("key");//删除指定key的键值对,如果该key不存在则出现异常
session.invalidate();//使session失效,立即使当前会话失效,原来会话中存储的所有对象都不能在被访问
session.getId();//获取当前会话的id,每个会话在服务器端都存在一个唯一标识sessionID,,session对象发送到浏览器的唯一数据就是sessionID,它一般被存储在cookie中
session.setMaxInactiveInterval(60*60*24);//设置会话的生命周期,单位为秒,负数表明会话永不失效
session.getMaxInActiveInterval();//获取会话的最大持续时间,使用时需要处理格式
session.idNew()//用来判断该session是否为新建立的
ajax中没有加下面那一句代码,该ajax方法就没办法进入当前会话中!!也没办法实现当前接口的存储会话功能。
$.ajax({
type:"POST",
url:'http://localhost:8080/user-login',
data:$("#from").,
dataType:'JSON',
withCredentials: true,//这一句话!
success:function(){}
error:function(){}
})
//上面那句话不行就换成下面这个:
//xhrFields: {
// withCredentials: true
//},
一开始用post来跨域,搞了一个下午,就被项目经理吐槽了:“post是什么鬼,你用post传别人根本不知道这是个什么东西!”
function Login() {
var url = "/do_login";
$.ajax({
url: url,
type: "post",
data: $("#loginFrom").serialize(),
success: function (data) {
console.log(data);
var json = eval(data);
var token = json.message;
console.log(token);
//token为后端加密后的用户名
//上面的url为本地请求的地址
//下面的url为跨域请求的地址,请求完后,2号服务器就存好session和对应的cookie,可直接访问主页而不被拦截
$.ajax({
url:"http://192.168.0.59:8080/userinfo/userinfoAction!getUserBy.action?actoken="+token,
type:"get",
success:function (data) {
console.log("success:"+data)
},
error:function (data) {
console.log("error:"+data)
}
})
},
error: function (data) {
}
})
}
我一开始以为cookie的setPath()和setDomain()方法很厉害,一直在尝试跨域存储,到头来没完成任务又跑去请教项目经理。
默认情况下cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得。
想实现跨域存储就在2号服务器上写一个接收的接口,1号服务器用get请求方式直接发送一个能达到目的的字段,当然,在企业应用开发中这个字段肯定是加了密的,比如两个服务器页面实现一方登陆,两方都实现登陆,这样就需要对用户名进行加密并用get方式将加密后的用户名传到2号服务器,不需验证密码,直接实现登陆,相当于第三方登陆,当然,这个加密肯定是会根据时间戳而改变的,不然太不安全了(①post请求无法实现跨域请求中的存session和cookie操作,②一个好的加密算法,连作者都解不了,也不需要解)