最近在作項目的時候遇見了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過時的問題的。