关于session的一些问题
最近在做项目的时候碰见了session过期的问题,然后就上网查了一些资料,我将我整理过的知识点梳理一下,顺便说一下我的使用方案。
Session存储在服务器端,一般为了防止在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时创建,需要注意只有访问JSP、Servlet等程序时才会创建Session,只访问HTML、IMAGE等静态资源并不会创建Session,可调用request.getSession(true)强制生成Session。
一、关于Session的一些基础知识
Session什么时候失效?
1. 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。
2. 调用Session的invalidate方法。
Session对浏览器的要求:
虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然需要客户端浏览器的支持。这是因为Session需要使用Cookie作为识别标志。HTTP协议是无状态的,Session不能依据HTTP连接来判断是否为同一客户,因此服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。
该Cookie为服务器自动生成的,它的maxAge属性一般为-1,表示仅当前浏览器内有效,并且各浏览器窗口间不共享,关闭浏览器就会失效。因此同一机器的两个浏览器窗口访问服务器时,会生成两个不同的Session。但是由浏览器窗口内的链接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,因此会共享一个Session。
注意:新开的浏览器窗口会生成新的Session,但子窗口除外。子窗口会共用父窗口的Session。例如,在链接上右击,在弹出的快捷菜单中选择"在新窗口中打开"时,子窗口便可以访问父窗口的Session。
如果客户端浏览器将Cookie功能禁用,或者不支持Cookie怎么办?例如,绝大多数的手机浏览器都不支持Cookie。Java Web提供了另一种解决方案:URL地址重写。
URL地址重写是对客户端不支持Cookie的解决方案。URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。这样即使客户端不支持Cookie,也可以使用Session来记录用户状态。HttpServletResponse类提供了encodeURL(String url)实现URL地址重写,该方法会自动判断客户端是否支持Cookie。如果客户端支持Cookie,会将URL原封不动地输出来。如果客户端不支持Cookie,则会将用户Session的id重写到URL中。
注意:TOMCAT判断客户端浏览器是否支持Cookie的依据是请求中是否含有Cookie。尽管客户端可能会支持Cookie,但是由于第一次请求时不会携带任何Cookie(因为并无任何Cookie可以携带),URL地址重写后的地址中仍然会带有jsessionid。当第二次访问时服务器已经在浏览器中写入Cookie了,因此URL地址重写后的地址中就不会带有jsessionid了。
来源于:http://www.cnblogs.com/binger/archive/2013/03/19/2970171.html session的生命周期
如果访问者在Session的设定的失效时间内(比如默认的20分钟)没有任何动作,Session就会失效,这个就意味着与Session存贮相关的变量也会同时失效,不能再访问。有时候我们需要保持Session很长的时间来等待用户完成工作,比如博客,当用户在写完文章之后提交却发现Session已经失效,这是一件多么悲惨的事情。
很多人可能尝试这样做
<system.web>
<authentication mode="Forms">
<forms timeout="60"/>
</authentication>
...
</system.web>
尽管我们可以很简单的增加Session的过期时间,但是这并不是一个很好的方案。当用户真的离开的时候,它会让你的服务器系统浪费很多内存资源来保存一些完全没有意义的东西。如果这个网站的访问量非常大的时候,可能由于Session占用的内存太多,而使你的网站运行得很慢。解决方案我们可以采用客户端周期性请求服务器的方法来保持Session。很多大型网站都是采用这样的方法,例如网易,51博客和QQ在写邮件和发文章的时候。为了达到这样的效果,我们可以使用javascript,jquery,metarefresh和asp.net ajax几种方法来解决。
1. 用javascript来保持Session
Asp.net 仅仅会记住用户的最后一次请求,它不知道用户是否关闭了浏览器,或者是否在干别的事情。为了保住那些还开着我们的网页的用户的Session,我们可以使用JS的setInterval功能
<%--
In this example, image will be used to keep session alive,
By changing image's src parameter, we'll make periodical requests
to web server.
--%>
<img id="imgSessionAlive" width="1" height="1" /> <script type="text/javascript" >
// Helper variable used to prevent caching on some browsers
var counter;
counter = 0; function KeepSessionAlive() {
// Increase counter value, so we'll always get unique URL
counter++; // Gets reference of image
var img = document.getElementById("imgSessionAlive"); // Set new src value, which will cause request to server, so
// session will stay alive
img.src = "http://YourWebSiteUrl.com/RefreshSessionState.aspx?c=" + counter; // Schedule new call of KeepSessionAlive function after 60 seconds
setTimeout(KeepSessionAlive, 60000);
} // Run function for a first time
KeepSessionAlive();
</script>
代码
在这个例子里,RefreshSessionState.aspx这个页面将会每分钟被请求一次。我们通过操作SRC来请求服务器。当然这只是一个巧妙的方法,你可以使用Http Request.当然那更加的麻烦。如果你只是想保住Session的话你可以设置为19分钟(19*60*1000=1140000)。当访问的间隔很小时,比如例子的一分钟,这样做的好处是你可以准确的知道用户的离开时间,并且立即释放掉不需要使用的资源。你甚至可以把Session的过期时间定为2分钟。这样你的服务器就只会保存当前停留在你网站的用户的Session.
因为RefreshSessionState.aspx页面会被每分钟请求,所以我们可以使用ASP.NET服务器技术来追踪我们的用户,例如统计当前用户数,用户在看那一个页面等等详细信息,如果是做一个社区性质的网站的话,相信这些会让你的网站绽放光彩的。
2. 使用JQUERY 保持Session
我们可以使用Jquery框架来完成相同的任务。这里我们使用Post提交方式来保持我们的Session
<script language="javascript" type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script language="javascript" type="text/javascript"> function KeepSessionAlive() {
// 1. Make request to server
$.post("http://YourWebSiteUrl.com/RefreshSessionState.aspx"); // 2. Schedule new request after 60000 miliseconds (1 minute)
setInterval(KeepSessionAlive, );
} // Initial call of function
KeepSessionAlive(); Â
</script>
代码
Jquery的简洁性是不是让你眼红呢?
3. 使用Meta Refresh来保持Session
一般我们不会用refresh来定时刷新我们的整个页面,因为这会造成你的页面一闪一闪,这可不是一闪一闪亮晶晶,你要是一闪一闪的用户早跑了。所以我们一般使用一个Iframe来完成这个功能
<iframe height="0" width="0" src="RefreshSessionState.aspx" frameborder="0" />
此时RefreshSessionState.aspx如果你不要跟踪用户的话不需要服务器代码。我习惯于这样写
<html>
<head>
<%
Response.Write(@"<meta http-equiv=""refresh"" content=""900;url=RefreshSessionState.aspx?x=" +
Server.UrlEncode(DateTime.Now.ToString()) + @""" />");
%>
</head>
<body> </body>
</html>
代码
参数x的作用是为了避免浏览器缓存整个页面导致我们需要的功能成为泡影,这样我们就通过了一个iframe来完成了我们需要的功能。
4. 使用asp.net ajax 来保持Session
Aspx页面的代码如下:
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<div> <asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="10000" ontick="Timer1_Tick">
</asp:Timer>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel> </div>
</form>
</body>
</html>
代码
Timer控件的Interval可是设置间隔时间但是是毫秒。服务器端的代码我们可以这样写:
using System; public partial class Ajax_Refresh : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
// Set session timeout to small value, in this case
// 2 minutes, to see quickly if Timer will keep session alive
Session.Timeout = ;
// Set some value in session
Session["Testing"] = "session is alive";
} // Timer will make request to server in regular time intervals
protected void Timer1_Tick(object sender, EventArgs e)
{
// Write current session value into label
Label1.Text = (string)Session["Testing"];
Label1.Text += "<br /> Last request at " + DateTime.Now.ToString();
}
}
代码
实际上在许多公司使用asp.netajax的比较少,但是如果是一些要求快速开发的项目来说,asp.net ajax也不愧为一个很好的选择。
以上就是保持延长Session的四种解决方案,希望对你有些帮助。
由于我们当前项目使用率不是太高,至于内存效率什么的都不在考虑范围之内,我直接用的就是最开始修改 <forms timeout="60"/>来解决session过期的问题的。
关于session的一些问题的更多相关文章
- session实现购物车
为实现简单的购物功能(购物车添加.账户查看.购物车商品删除.实时的购物商品数量及价格的计算显示.购物车商品数量可手动输入等),用session实现了一简单的以php语言为基础.连接MySQL数据库的购 ...
- Asp.net Core中使用Session
前言 2017年就这么悄无声息的开始了,2017年对我来说又是特别重要的一年. 元旦放假在家写了个Asp.net Core验证码登录, 做demo的过程中遇到两个小问题,第一是在Asp.net Cor ...
- 懒加载session 无法打开 no session or session was closed 解决办法(完美解决)
首先说明一下,hibernate的延迟加载特性(lazy).所谓的延迟加载就是当真正需要查询数据时才执行数据加载操作.因为hibernate当中支持实体对象,外键会与实体对象关联起来.如 ...
- 探索ASP.NET MVC5系列之~~~6.Session篇(进程外Session)
其实任何资料里面的任何知识点都无所谓,都是不重要的,重要的是学习方法,自行摸索的过程(不妥之处欢迎指正) 汇总:http://www.cnblogs.com/dunitian/p/4822808.ht ...
- Nhibernate的Session管理
参考:http://www.cnblogs.com/renrenqq/archive/2006/08/04/467688.html 但这个方法还不能解决Session缓存问题,由于创建Session需 ...
- nginx+iis+redis+Task.MainForm构建分布式架构 之 (redis存储分布式共享的session及共享session运作流程)
本次要分享的是利用windows+nginx+iis+redis+Task.MainForm组建分布式架构,上一篇分享文章制作是在windows上使用的nginx,一般正式发布的时候是在linux来配 ...
- zookeeper源码分析之六session机制
zookeeper中session意味着一个物理连接,客户端连接服务器成功之后,会发送一个连接型请求,此时就会有session 产生. session由sessionTracker产生的,sessio ...
- [转载]Cookie/Session的机制与安全
Cookie和Session是为了在无状态的HTTP协议之上维护会话状态,使得服务器可以知道当前是和哪个客户在打交道.本文来详细讨论Cookie和Session的实现机制,以及其中涉及的安全问题. 因 ...
- 修改session垃圾回收几率
<?php //修改session垃圾回收几率 ini_set('session.gc_probability','1'); ini_set('session.gc_divisor','2'); ...
- Nginx反向代理,负载均衡,redis session共享,keepalived高可用
相关知识自行搜索,直接上干货... 使用的资源: nginx主服务器一台,nginx备服务器一台,使用keepalived进行宕机切换. tomcat服务器两台,由nginx进行反向代理和负载均衡,此 ...
随机推荐
- nginx跨站访问,防盗链
跨站访问 从网站A利用AJAX跨站访问网站B 浏览器会根据服务端返回的头部信息(Access-Control-Allow-Origin)判断是否允许跨域访问.如果服务端都允许跨站访问,浏览器段也就没必 ...
- 适合没有ui的项目的样式
官网: https://www.tailwindcss.cn/
- java多线程批量下载文件
多线程下载文件 平时开发中有时会用到文件下载,为了提高文件的下载速率,采用多线程下载能够达到事半功倍的效果: package test; /** * 文件下载类 * @author luweichen ...
- codevs 1094 FBI树 2004年NOIP全国联赛普及组 x
题目描述 Description 我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串. ...
- K8s中RS和Deployment
什么是ReplicaSet? ReplicaSet是下一代复本控制器.ReplicaSet和 Replication Controller之间的唯一区别是现在的选择器支持.Replication Co ...
- java中报错:problem with class file or dependent class; nested exception is java.lang.NoClassDefFoundError
今天和往常一样打开项目,竟然报错problem with class file or dependent class; nested exception is java.lang.NoClassDef ...
- http状态码301和302详解及区别——辛酸的探索之路
原文链接:https://blog.csdn.net/grandPang/article/details/47448395 一直对http状态码301和302的理解比较模糊,在遇到实际的问题和翻阅各种 ...
- CTF MD5之守株待兔,你需要找到和系统锁匹配的钥匙
这是提示 从系统锁下手,通过get方式key字段提交答案,直到您的钥匙与系统锁相等则成功. 点开链接可以发现有两串字符,而且系统的秘钥是一直在变化的 题目中已经给了MD5加密,那么用MD5解密发现您的 ...
- OSI7层模型
为什么来写一个osi7层模型的随便呐? 因为自己对osi模型一点不熟悉 只知道里面的协议 要学渗透必先学习osi 这是一个osi7层的大体图片 接下来我们会对每一层进行详细的解答 这是五层模型 接下来 ...
- TP-四种url访问的方式
url的4种访问方式 (这是重点!!) 1.PATHINFO 模式 --重点 在后面使用非常多,如果想传多个参数可以使用键1/值1/键2/值2方法 代码如下: http://域名/项目名/入口文 ...