最近在作项目的时候遇见了session过时的问题,而后就上网查了一些资料,我将我整理过的知识点梳理一下,顺便说一下个人使用方案。javascript
Session存储在服务器端,通常为了防止在服务器的内存中(为了高速存取),Sessinon在用户访问第一次访问服务器时建立,须要注意只有访问JSP、Servlet等程序时才会建立Session,只访问HTML、IMAGE等静态资源并不会建立Session,可调用request.getSession(true)强制生成Session。html
1、关于Session的一些基础知识java
Session何时失效?jquery
1. 服务器会把长时间没有活动的Session从服务器内存中清除,此时Session便失效。Tomcat中Session的默认失效时间为20分钟。web
2. 调用Session的invalidate方法。ajax
Session对浏览器的要求:浏览器
虽然Session保存在服务器,对客户端是透明的,它的正常运行仍然须要客户端浏览器的支持。这是由于Session须要使用Cookie做为识别标志。HTTP协议是无状态的,Session不能依据HTTP链接来判断是否为同一客户,所以服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id(也就是HttpSession.getId()的返回值)。Session依据该Cookie来识别是否为同一用户。缓存
该Cookie为服务器自动生成的,它的maxAge属性通常为-1,表示仅当前浏览器内有效,而且各浏览器窗口间不共享,关闭浏览器就会失效。所以同一机器的两个浏览器窗口访问服务器时,会生成两个不一样的Session。可是由浏览器窗口内的连接、脚本等打开的新窗口(也就是说不是双击桌面浏览器图标等打开的窗口)除外。这类子窗口会共享父窗口的Cookie,所以会共享一个Session。服务器
注意:新开的浏览器窗口会生成新的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, 60000); } // 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 = 2; // 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过时的问题的。