複製鏈接
請複製以下鏈接發送給好友

session

(計算機術語)

鎖定
Session:在計算機中,尤其是在網絡應用中,稱為“會話控制”。Session對象存儲特定用户會話所需的屬性及配置信息。這樣,當用户在應用程序的Web頁之間跳轉時,存儲在Session對象中的變量將不會丟失,而是在整個用户會話中一直存在下去。當用户請求來自應用程序的 Web頁時,如果該用户還沒有會話,則Web服務器將自動創建一個 Session對象。當會話過期或被放棄後,服務器將終止該會話。Session 對象最常見的一個用法就是存儲用户的首選項。例如,如果用户指明不喜歡查看圖形,就可以將該信息存儲在Session對象中。有關使用Session 對象的詳細信息,請參閲“ASP應用程序”部分的“管理會話”。注意會話狀態僅在支持cookie的瀏覽器中保留。
中文名
時域
外文名
Session
所屬學科
計算機網絡
應用學科
軟件 網絡通信
屬    性
用户與交互系統通信的時間間隔

session監控系統

為了滿足實時遠程監測系統的需求,服務器需要實時監測客户端的連接狀態。為此利用ICE中間件的優點設計了一種基於面向對象ICE中間件自定義Session機制的解決方案。 [1] 
基本定義
Session直接翻譯成中文比較困難,一般都譯成時域。在計算機專業術語中,Session是指一個終端用户與交互系統進行通信的時間間隔,通常指從註冊進入系統到註銷退出系統之間所經過的時間。以及如果需要的話,可能還有一定的操作空間
需要注意的是,一個Session的概念需要包括特定的客户端,特定的服務器端以及不中斷的操作時間。A用户和C服務器建立連接時所處的Session同B用户和C服務器建立連接時所處的Session是兩個不同的Session。
session的工作原理:
(1)當一個session第一次被啓用時,一個獨一的標識被存儲於本地的cookie中。
(2)首先使用session_start()函數,PHP從session倉庫中加載已經存儲的session變量。
(3)當執行PHP腳本時,通過使用session_register()函數註冊session變量。
(4)當PHP腳本執行結束時,未被銷燬的session變量會被自動保存在本地一定路徑下的session庫中,這個路徑可以通過php.ini文件中的session.save_path指定,下次瀏覽網頁時可以加載使用。
解決方案
那什麼是Session的解決方案呢?用户訪問一個網站時往往需要瀏覽許多網頁。Session的使用在不同的語言中的使用方法特點不盡相同。對於一個通過PHP構築的網站來説,用户在訪問的過程中需要執行許多的PHP腳本。然而由於HTTP協議自身的特點,用户每執行一個PHP腳本都需要和Web服務器重新建立連接。
又由於無狀態記憶的特點,此次連接無法得到上次連接的狀態。這樣,用户在一個PHP腳本中對一個變量進行了賦值操作,而在另外一個PHP腳本中卻無法得到這個變量的值。例如,用户在負責登錄的PHP腳本中設置了$user="wind",卻無法在另一個PHP腳本中通過調用$user來獲得“wind”這個值。也就是説,在一次HTTP請求中,PHP無法將已經賦值的參數傳遞給下一次http請求的腳本。因此,每個PHP腳本中所定義的變量都是隻在本次HTTP請求內有效,本次HTTP請求結束,PHP就會釋放掉這些為這些變量分配的內存。
Session解決方案,就是要提供在PHP腳本中定義全局變量的方法,使得這個全局變量在同一個Session中對於所有的PHP腳本都有效。提到了,Session不是一個簡單的時間概念,一個Session中還包括了特定的用户和服務器。因此更詳細地講,在一個Session定義的全局變量的作用範圍,是指這個Session所對應的用户所訪問的所有PHP。
例如A用户通過Session定義了一個全局變量$user=“wind”中,而B用户通過Session定義的全局變量$user=“jane”。那麼在A用户所訪問的PHP腳本中,$user的值就是wind。 [1] 
使用方法
Session 是 用於保持狀態的基於Web服務器的方法。Session允許通過將對象存儲在Web服務器的內存中在整個用户會話過程中保持任何對象。
Session通常用於執行以下操作
存儲需要在整個用户會話過程中保持其狀態的信息,例如登錄信息或用户瀏覽Web應用程序時需要的其它信息。
存儲只需要在頁面重新加載過程中或按功能分組的一組頁之間保持其狀態的對象。
Session的作用就是它在Web服務器上保持用户的狀態信息供在任何時間從任何設備上的頁面進行訪問。因為瀏覽器不需要存儲任何這種信息,所以可以使用任何瀏覽器,即使是像Pad或手機這樣的瀏覽器設備。
持久性方法的限制
隨着越來越多用户登錄,Session所需要的服務器內存量也會不斷增加。
訪問Web應用程序的每個用户都生成一個單獨的Session對象。每個Session對象的持續時間是用户訪問的時間加上不活動的時間。
如果每個Session中保持許多對象,並且許多用户同時使用Web應用程序(創建許多Session),則用於 Session持久性的服務器內存量可能會很大,從而影響了可伸縮性 [1] 

session實用精解

cookies和session,JSP基本語法,JSP使用JavaBean,整合Servlet和JSP(MVC),JSP表達式語言,JSP自制標籤,數據庫JDBC,網絡安全,Servlet和JSP過濾器,Web應用事件監聽器,具體內容如下: [2] 
基本語法
1、對於值類型的變量,Session中保存的是值類型的拷貝
Session["__test0"] = 1;
int i = (int)Session["__test0"]+1;
int j = (int)Session["__test0"];
結果:i=2,j=1
2、對於引用類型的變量,Session中保存的是引用
CDACommon cda = new CDACommon();
Session["__test"] = cda.GetDataSet("select top 1 * from tb_customer");
DataSet ds = (DataSet)Session["__test"];
DataSet ds2 = (DataSet)Session["__test"];
ds.Tables[0].Rows[0][0]="9999";
結果:
ds.Tables[0].Rows[0][0]=="9999"
ds2.Tables[0].Rows[0][0]=="9999";
3、Session週期
新的瀏覽器窗口啓動後,開始一個新的Session,觸發Global的Session_Start的調用,從第一個瀏覽器窗口打開的瀏覽器窗口不啓動新的Session。Session過期後,執行頁面的提交也會觸發Session_Start,等於是新的一個Session。
4、調用Session
對於Web Service,每個方法的調用都會啓動一個Session,可以用下面的方法來使多個調用在同一個Session裏 :
CWSSyscfg cwsCfg = new CWSSyscfg(); cwsCfg.CookieContainer = new System Net.CookieContainer(); CWSSyscfg是一個Web Service類,Web Service的給代理類設置CookieContainer屬性,只要多個代理的CookieContainer屬性是相同的值,則對這些Web Service的調用在同一個Session。可以用單例模式來實現。
5、Session數據有效期
只要頁面有提交活動,則Session的所有項都會保持,頁面在20分鐘(默認配置)內沒有任何提交活動時Session會失效。Session內存儲的多個數據項是整體失效的。
6、Session的保存
在Session中如果保存的是非序列化的類比如DataView,在用SQLServer保存Session的模式下,無法使用。查看一個類是否是序列化的方法是,需看是否用[Serializable]來標記了該類。
在PHP中
PHP session變量用於存儲關於用户會話(session)的信息,或者更改用户會話(session)的設置。Session變量存儲單一用户的信息,並且對於應用程序中的所有頁面都是可用的。
PHP Session變量:
您在計算機上操作某個應用程序時,您打開它,做些更改,然後關閉它。這很像一次對話(Session)。計算機知道您是誰。它清楚您在何時打開和關閉應用程序。然而,在因特網上問題出現了:由於HTTP地址無法保持狀態,Web服務器並不知道您是誰以及您做了什麼
PHP session解決了這個問題,它通過在服務器上存儲用户信息以便隨後使用(比如用户名稱、購買商品等)。然而,會話信息是臨時的,在用户離開網站後將被刪除。如果您需要永久存儲信息,可以把數據存儲在數據庫中。
Session的工作機制是:為每個訪客創建一個獨一的id (UID),並基於這個UID來存儲變量。UID存儲在cookie 中,或者通過URL進行傳導。 [2] 
在JSP中
Jsp的session是使用bean的一個生存期限,一般為page,session意思是在這個用户沒有離開網站之前一直有效,如果無法判斷用户何時離開,一般依據系統設定,tomcat中設定為30分鐘。
使用session功能,可以達到多個jsp程序從操作同一個java bean,那麼這個java bean可以作為傳統意義上的"全局變量池".(在java中可以使用static靜態化一個變量和方法,使用singleton獨一化對象。)
在項目實踐中,Jsp程序中很多參數需要從數據庫中讀取,有的參數實際讀取一次就可以,如果設計成每個用户每產生一個頁面都要讀取數據庫,很顯然,數據庫的負載很大,同時也浪費時間,雖然可能有數據庫連接池優化,但是儘量少使用數據庫是我們編程的原則。
JSP使用一個叫HttpSession的對象實現同樣的功能。HTTPSession是一個建立在cookies 和URL-rewriting上的高質量的界面。Session的信息保存在服務器端,Session的id保存在客户機的cookie中。事實上,在許多服務器上,如果瀏覽器支持的話它們就使用cookies,但是如果不支持或廢除了的話就自動轉化為URL-rewriting,session自動為每個流程提供了方便地存儲信息的方法。
Httpsession具有如下API
getId 此方法返回獨一的標識,這些標識為每個session而產生。當只有一個單一的值與一個session聯合時,或當日志信息與先前的sessions有關時,它被當作鍵名用。
GetCreationTime 返回session被創建的時間。最小單位為千分之一秒。為得到一個對打印輸出很有用的值,可將此值傳給Date constructor 或者GregorianCalendar的方法setTimeInMillis.
GetLastAccessedTime 返回session最後被客户發送的時間。最小單位為千分之一秒。
GetMaxInactiveInterval 返回總時間(秒),負值表示session永遠不會超時。
getAttribute 取一個session相聯繫的信息。(在jsp1.0中為 getValue)。
Integer item = (Integer) session.getAttribute("item") //檢索出session的值並轉化為整型
setAttribute 提供一個關鍵詞和一個值。會替換掉任何以前的值。(在jsp1.0中為putValue)。
session.setAttribute("ItemValue", itemName); // ItemValue 必須不是must簡單類型
在應用中使用最多的是getAttribute和setAttribute。現以一個簡單的例子來説明session的應用,test1.jsp(信息寫入session),test2.jsp(從session讀出信息)。
test1.jsp
<HTML>
<HEAD>
<TITLE> Document </TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<%
session.setAttribute("str",new String(“this is test”));
%>
</BODY>
</HTML>
test2.jsp
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF">
<%
String ls_str=null;
ls_str=(String)session.getAttribute("str");
out.println(“從session裏取出的值為:”+ls_str);
%>
</BODY>
</HTML>
使用詳解
php中的Session與Cookie
在PHP開發中對比起Cookie,session是存儲在服務器端的會話,相對安全,並且不像Cookie那樣有存儲長度限制,簡單介紹session的使用。
由於Session是以文本文件形式存儲在服務器端的,所以不怕客户端修改Session內容。實際上在服務器端的Session文件,PHP自動修改session文件的權限,只保留了系統讀和寫權限,而且不能通過ftp修改,所以安全得多。
對於Cookie來説,假設要驗證用户是否登陸,就必須在Cookie中保存用户名和密碼(可能是md5加密後字符串),並在每次請求頁面的時候進行驗證。如果用户名和密碼存儲在數據庫,每次都要執行一次數據庫查詢,給數據庫造成多餘的負擔。因為並不能只做一次驗證。為什麼呢? 因為客户端Cookie中的信息是有可能被修改的。假如你存儲$admin變量來表示用户是否登陸,$admin為true的時候表示登陸,為false的時候表示未登錄,在第一次通過驗證後將$admin等於true存儲在Cookie,下次就不用驗證了是錯的,假如有人偽造一個值為true的$admin變量, 非常的不安全。
而Session就不同了,Session是存儲在服務器端的,遠程用户沒辦法修改session文件的內容,因此可以單純存儲一個$admin變量來判斷是否登陸,首次驗證通過後設置$admin值為true,以後判斷該值是否為true,假如不是,轉入登陸界面,這樣就可以減少很多數據庫操作了。而且可以減少每次為了驗證Cookie而傳遞密碼的不安全性了(session驗證只需要傳遞一次,假如你沒有使用SSL安全協議的話)。即使密碼進行了md5加密,也是很容易被截獲的。
當然使用session還有很多優點,比如控制容易,可以按照用户自定義存儲等(存儲於數據庫)。
session在php.ini一般不需要設置,因為並不是每個人都有修改PHP.ini的權限,默認session 的存放路徑是服務器的系統臨時文件夾,可以自定義存放在自己的文件夾裏。
Php如何創建Session
開始介紹如何創建session。非常簡單,真的。
啓動session會話,並創建一個$admin變量:
// 啓動session
session_start();
// 聲明一個名為admin的變量,並賦空值
$_session["admin"] = null;
>
如果你使用了Session,或者該PHP文件要調用Session變量,那麼就必須在調用Session之前啓動它,使用 session_start()函數。其它都不需要你設置了,PHP自動完成session文件的創建。
執行完這個程序後,可以到系統臨時文件夾找到這個 session 文件,一般文件名形如:sess_4c83638b3b0dbf65583181c2f89168ec,後面是32位編碼後的隨機字符串。用編輯器打開它,看一下它的內容:
admin|N;
Session是什麼呢? 簡單來説就是服務器給客户端的一個編號。當一台WWW服務器運行時,可能有若干個用户瀏覽正在運行這台服務器上的網站。當每個用户首次與這台WWW服務器建立連接時,他就與這個服務器建立了一個Session,同時服務器會自動為其分配一個SessionID,用以標識這個用户的身份。這個SessionID是由WWW服務器隨機產生的一個由24個字符組成的字符串。
這個的SessionID是有很大的實際意義的。當一個用户提交了表單時,瀏覽器會將用户的SessionID自動附加在HTTP頭信息中,(這是瀏覽器的自動功能,用户不會察覺到),當服務器處理完這個表單後,將結果返回給SessionID所對應的用户。試想,如果沒有SessionID,當有兩個用户同時進行註冊時,服務器怎樣才能知道到底是哪個用户提交了哪個表單呢。當然,SessionID還有很多其他的作用。
除了SessionID,在每個Session中還包含很多其他信息。但是對於編寫ASP或ASP .NET的程序員來説,最有用的還是可以通過訪問ASP/ASP .NET的內置Session對象,為每個用户存儲各自的信息。例如我們想了解一下訪問我們網站的用户瀏覽了幾個頁面,我們可能在用户可能訪問到每個的頁面中加入:
<% If Session("PageViewed") = ""Then Session("PageViewed") = 1 Else Session("PageViewed") = Session("PageViewed") + 1 End If %>
通過以下這句話可以讓用户得知自己瀏覽了幾個頁面:
<% Response.Write("You have viewed " & Session("PageViewed") & " pages") %>
可能有些讀者會問:這個看似像是數組的Session(“..”)是哪裏來的? 需要我定義嗎? 實際上,這個Session對象是具有ASP解釋能力的的WWW服務器的內建對象。也就是説ASP的系統中已經給你定義好了這個對象,你只需要使用就行了。其中Session(“..")中的..就好像變量名稱,Session(“..")=$$中的$$就是變量的值了。你只需要寫上句話,在這個用户的每個頁面中都可以訪問..變量中的值了。
其實ASP會話一共內建了7個對象,有Session、Application、Cookie、Response、Request、Server等。在其他的服務器端腳本語言如JSP、PHP等中也有其類似的對象,只是叫法或者使用方法上不太一樣。
一般內容結構
變量名|類型:長度:值;
並用分號隔開每個變量。有些是可以省略的,比如長度和類型。
來看一下驗證程序,假設數據庫存儲的是用户名和md5加密後的密碼:
//表單提交後...
$posts = $_POST;
// 清除一些空白符號
foreach ($posts as $key => $value)
{
$posts[$key] = trim($value);
}
$password = md5($posts["password"]);
$username = $posts["username"];
$query = "SELECT `username` FROM `user` WHERE `password` = '$password'";
// 取得查詢結果
$userInfo = $DB->getRow($query);
if (!empty($userInfo))
{
if ($userInfo["username"] == $username)
{
// 當驗證通過後,啓動session
session_start();
// 註冊登陸成功的admin變量,並賦值true
$_SESSION["admin"] = true;
}
else
{
die("用户名密碼錯誤");
}
}
else
{
die("用户名密碼錯誤");
}
在需要用户驗證的頁面啓動session,判斷是否登陸:
// 防止全局變量造成安全隱患
$admin = false;
// 啓動會話,這步必不可少
session_start();
// 判斷是否登陸
if (isset($_SESSION["admin"]) && $_SESSION["admin"] == true)
{
echo "您已經成功登陸";
}
else
{
// 驗證失敗,將 $_session["admin"] 置為 false
$_SESSION["admin"] = false;
die("您無權訪問");
}
>
是不是很簡單呢?將 $_session 看成是存儲在服務器端的數組即可,註冊的每一個變量都是數組的鍵,跟使用數組沒有什麼分別。
如果要登出系統怎麼辦?銷燬 session 即可。
<?php
session_start();
// 這種方法是將原來註冊的某個變量銷燬
unset($_SESSION["admin"]);
// 這種方法是銷燬整個 session 文件
session_destroy();
>
釋放當前在內存中已經創建的所有$_SESSION變量,但不刪除session文件以及不釋放對應的session id
<?php
session_start();
session_unset();
session_destroy();
session_write_close();
setcookie(session_name(),'',0,'/');
session_regenerate_id(true);
?>
session_destroy()
刪除當前用户對應的session文件以及釋放session id,內存中的$_SESSION變量內容依然保留
因此,釋放用户的session所有資源,需要順序執行如下代碼:
<?php
$_SESSION['user'] = ‘user1′;
session_unset();
session_destroy();
?>
Session能否像Cookie那樣設置生存週期呢?有了Session是否就完全拋棄Cookie呢?想説的是,結合Cookie來使用session才是最方便的。
Session是如何來判斷客户端用户的呢?它是通過Session ID來判斷的,什麼是Session ID,就是那個Session文件的文件名,Session ID是隨機生成的,因此能保證獨特性和隨機性,確保Session的安全。一般如果沒有設置Session的生存週期,則Session ID存儲在內存中,關閉瀏覽器後該ID自動註銷,重新請求該頁面後,重新註冊一個session ID。
如果客户端沒有禁用Cookie,則Cookie在啓動Session會話的時候扮演的是存儲Session ID和session生存期的角色。
來手動設置session的生存期:
session_start();
// 保存一天
$lifeTime = 24 * 3600;
setcookie(session_name(),session_id(),time() + $lifeTime,"/");
>
其實Session還提供了一個函數session_set_cookie_params(); 來設置Session的生存期的,該函數必須在 session_start()函數調用之前調用:
// 保存一天
<?php
$lifeTime = 24 * 3600;
session_set_cookie_params($lifeTime);
session_start();
$_session["admin"] = true;
>
如果客户端使用IE6.0 , session_set_cookie_params(); 函數設置Cookie會有些問題,所以還是手動調用setcookie函數來創建cookie。
假設客户端禁用Cookie怎麼辦?沒辦法,所有生存週期都是瀏覽器進程了,只要關閉瀏覽器,再次請求頁面又得重新註冊Session。那麼怎麼傳遞Session ID呢? 通過URL或者通過隱藏表單來傳遞,PHP會自動將session ID發送到URL 上,URL形如:?PHPSESSID=bba5b2a240a77e5b44cfa01d49cf9669,其中URL中的參數PHPSESSID就是Session ID了,可以使用$_GET來獲取該值,從而實現session ID頁面間傳遞。
// 保存一天
<?php
$lifeTime = 24 * 3600;
// 取得當前session 名,默認為PHPSESSID
$sessionName = session_name();
// 取得session ID
$sessionID = $_GET[$sessionName];
// 使用session_id()設置獲得的session ID
session_id($sessionID);
session_set_cookie_params($lifeTime);
session_start();
$_session["admin"] = true;
>
對於虛擬主機來説,如果所有用户的Session都保存在系統臨時文件夾裏,將給維護造成困難,而且降低了安全性,可以手動設置Session文件的保存路徑,session_save_path()就提供了這樣一個功能。可以將session存放目錄指向一個不能通過Web方式訪問的文件夾,當然,該文件夾必須具備可讀寫屬性。
<?php
// 設置一個存放目錄
$savePath = "./session_save_dir/";
// 保存一天
$lifeTime = 24 * 3600;
session_save_path($savePath);
session_set_cookie_params($lifeTime);
session_start();
$_session["admin"] = true;
>
同 session_set_cookie_params(); 函數一樣,session_save_path()函數也必須在session_start()函數調用之前調用。
還可以將數組,對象存儲在session中。操作數組和操作一般變量沒有什麼區別,而保存對象的話,PHP會自動對對象進行序列化(也叫串行化),然後保存於session中。下面例子説明了這一點: [2] 
<?php
class person
{
var $age;
function output() {
echo $this->age;
}
function setAge($age) {
$this->age = $age;
}
}
>
setage.PHP
<?php
session_start();
require_once "person.PHP";
$person = new person();
$person->setAge(21);
$_session['person'] = $person;
echo "check here to output age";
>
output.PHP
<?php
// 設置回調函數,確保重新構建對象。
ini_set('unserialize_callback_func','mycallback');
function mycallback($classname) {
$classname . ".PHP";
}
session_start();
$person = $_session["person"];
// 輸出21
$person->output();
>
當執行setage.php文件的時候,調用了setage()方法,設置了年齡為21,並將該狀態序列化後保存在session 中(PHP將自動完成這一轉換),當轉到output.php後,要輸出這個值,就必須反序列化剛才保存的對象,又因為在解序列化的時候需要實例化一個未定義類,所以定義了以後回調函數,自動包含person.PHP這個類文件,因此對象被重構,並取得當前age的值為21,然後調用output()方法輸出該值。 [2] 
如何防止session超時
眾所周知,當用户登錄網站後較長一段時間沒有與服務器進行交互,將會導致服務器上的用户會話數據(即session)被銷燬。此時,當用户再次操作網頁時,如果服務器進行了session校驗,那麼瀏覽器將會提醒用户session超時。
那麼,如何解決用户登錄後較長時間未操作而導致的session失效的問題呢?
導致這個問題的關鍵詞有兩個:一個是「長時間」,一個是「未操作」。
1、如果用户未操作的「長時間」超過了服務器配置的session超時時間,並導致session失效,那麼我們延長session的超時時間,讓用户原來的「長時間」與超時時間相比,變得不「長」,不就可以解決了嗎?
2、如果用户是長時間「未操作」導致session失效,那麼想辦法產生「操作」,讓用户每隔一小段時間就「操作」一次,與服務器產生交互,那麼session自然也不會失效。一般情況下下,我們首先想到的是,通過改變服務器的配置,延長服務器的session超時時間。例如,在Tomcat服務器的web.xml文件中有如下節點內容:
<session-config><session-timeout>30</session-timeout></session-config>
這裏的30表示session的超時時間,單位為分鐘,如果用户登錄後在30分鐘內沒有與服務器交互,那麼當前用户的session將失效。我們可以配置一個更大的數值(比如60),就可以延長session的超時時間,如果將該值改為0或負數的話,則表示session永不失效。
不過在實際的工作應用中,一味地上調session的超時時間設置並不怎麼常見,大多數需要實現該功能的網站都將解決問題的焦點集中在第二條思路上。例如:一些在線網站均採用定時刷新頁面的方法來防止session超時。 [2] 
定時刷新頁面,最常見的有兩種實現方式:一種是通過JavaScript+HTMLDOM,另一種則是通過meta標籤來實現。
1、JavaScript+HTMLDOM,示例代碼如下:
functionrefresh(seconds){
setTimeout("self.location.reload()",seconds*1000);
}
refresh(600);//調用方法啓動定時刷新,數值單位:秒。
2、通過meta標籤來實現(在頁面中添加meta標籤refresh也可以指定每隔指定時間就刷新當前頁面),示例代碼如下:
<metahttp-equiv="refresh"content="600"/>
meta標籤可以實現每過600秒就刷新一次當前頁面。
在兩種方案中,較好的為第二種,因為如果當前頁面是在IE瀏覽器的模式窗口中打開的,默認情況下,self.location.reload()方法將會失效,而refreshmeta標籤在IE模式窗口下仍然有效。
兩種方式都實現了刷新當前頁面,並且使用起來非常簡單,不過很遺憾的是,它們存在一種幾乎致命的缺陷。試想一下,如果在論壇發帖等需要用户輸入內容的頁面,用户花費較長的時間輸入了許多文本內容,可是突然遇到了一個定時頁面刷新,結果用户輸入的所有內容都沒了,估計這個時候用户連掐死你的心都有了……
因此需要在當前頁面本身不刷新、不影響用户的任何操作的情況下實現定時刷新。最常見的解決方法仍然有兩種。一種是在當前頁面添加一個隱藏的iframe,然後在該iframe裏面實現定時刷新。
<iframeid="hidden_iframe"style="display:none;"scrolling="no"frameborder="0"name="hidden_iframe"src="ping.php"></iframe>
此外,需要在服務器上編寫對應的請求響應代碼,例如ping.php中可以編寫如下代碼:
<?php
//每隔600秒刷新當前頁面
echo'<html><head><metahttp-equiv="refresh"content="600"/></head><body></body></html>';
?>
另外一種則是使用JavaScriptImage對象來實現定時刷新,JavaScript代碼如下:
functionautoRefresh(seconds){
if(typeofperiod=="undefined"){//如果是第一次執行
period=seconds*1000;//定義全局變量period
varbodyDOM=document.getElementsByTagName("body")[0];
if(bodyDOM){
bodyDOM.innerHTML+='<imgid="auto_refresh_img"src=""style="display:none"/>';//添加隱藏的圖片
imgDOM=document.getElementById("auto_refresh_img");//定義全局Image對象
}
}
if(typeofimgDOM!="undefined"){
imgDOM.src="ping.php?sid="+newDate().getTime();//防止緩存
setTimeout("autoRefresh("+seconds+")",period);
}
}
autoRefresh(600);//調用方法啓動定時刷新
和使用iframe來實現定時刷新一樣,使用JavaScriptImage對象實現定時刷新,也需要在服務器端編寫類似的請求響應代碼。服務器的響應可以是文字等非圖片內容,非圖片內容只會造成圖像加載失敗,而圖像標籤本身就是隱藏的,不管是加載成功還是失敗都不會顯示,畢竟我們的主要目的是發送請求給服務器,讓服務器保持session處於活動狀態。
當然,還可以使用Ajax來實現定時刷新,不過使用Image對象會更好一些,因為有些老式瀏覽器的JavaScript無法實現Ajax,但是卻可以使用Image對象。此外,使用Ajax需要編寫更多的代碼來處理XMLHttpRequest等對象的活動。
在兩種方式中,各有其優缺點。
使用iframe標籤實現定時刷新的優點是:不需要編寫JavaScript代碼,可以在瀏覽器禁用JavaScript的情況下實現定時刷新;其缺點是:在某些不支持iframe標籤的老式瀏覽器中沒有效果,此外,iframe標籤在瀏覽器中新增加了一個獨立的頁面,即使沒有顯示出來,不過其內部解析的window、document等對象仍然存在,佔用的瀏覽器內存相對較多。
使用Image對象的優點是:與iframe相比,佔用的內存相對較少,支持Image的瀏覽器也相對較多(現代瀏覽器均支持);缺點是:在瀏覽器禁用JavaScript的情況下就毫無用武之地了。
開發人員應根據實際需求情況來確定使用何種實現方式更好。此外,服務器在響應定時刷新的請求時,在滿足要求的情況下,應返回儘可能少的數據,以節省帶寬。 [2] 

session比較分析

由於HTTP協議無狀態的缺陷。WEB的設計者們提出了Cookie和Session兩種解決機制。通過對兩者的比較分析,指出了它們的聯繫與區別。 [3] 
有效期
PHP中的session有效期默認是1440秒(24分鐘)【weiweiok 注:php5裏默認的是180分】,也就是説,客户端超過24分鐘沒有刷新,當前session就會失效。很明顯,這是不能滿足需要的。
一個已知管用的方法是,使用session_set_save_handler,接管所有的session管理工作,一般是把session信息存儲到數 據庫,這樣可以通過SQL語句來刪除所有過期的session,精確地控制session的有效期。這也是基於PHP的大型網站常用的方法。但是,一般的小型網站,似乎沒有必要這麼勞師動眾。
但是一般的Session的生命期有限,如果用户關閉了瀏覽器,就不能保存Session的變量了!那麼怎麼樣可以實現Session的永久生命期呢?
大家知道,Session儲存在服務器端,根據客户端提供的SessionID來得到這個用户的文件,然後讀取文件,取得變量的值,SessionID可以 使用客户端的Cookie或者Http1.1協議的Query_String(就是訪問的URL的“?”後面的部分)來傳送給服務器,然後服務器讀取Session的目錄……
要實現Session的永久生命期,首先需要了解一下php.ini關於Session的相關設置(打開php.ini文件,在“[Session]”部分):
1、session.use_cookies:默認的值是“1”,代表SessionID使用Cookie來傳遞,反之就是使用Query_String來傳遞;
2、session. name:這個就是SessionID儲存的變量名稱,可能是Cookie,也可能是Query_String來傳遞,默認值是“PHPSESSID”;
3、session.cookie_lifetime:這個代表SessionID在客户端Cookie儲存的時間,默認是0,代表瀏覽器一關閉SessionID就作廢……就是因為這個所以Session不能永久使用!
4、session.gc_maxlifetime:這個是Session數據在服務器端儲存的時間,如果超過這個時間,那麼Session數據就自動刪除!
ASP的開發人員都正在使用Session這一強大的功能,但是在使用的過程中卻發現了ASP Session有以下缺陷:
進程依賴性
ASP Session狀態存於IIS的進程中,也就是inetinfo.exe這個程序。所以當inetinfo.exe進程崩潰時,這些信息也就丟失。另外,重起或者關閉IIS服務都會造成信息的丟失。
Session狀態使用範圍的侷限性
當一個用户從一個網站訪問到另外一個網站時,這些Session信息並不會隨之遷移過去。例如:新浪網站的WWW服務器可能不止一個,一個用户登錄之後要去各個頻道瀏覽,但是每個頻道都在不同的服務器上,如果想在這些WWW服務器共享Session信息怎麼辦呢?
Cookie的依賴性
實際上客户端的Session信息是存儲在Cookie中的,如果客户端完全禁用掉了Cookie功能,他也就不能享受到了Session提供的功能了。
鑑於ASP Session的以上缺陷,微軟的設計者們在設計開發 ASP .NET Session時進行了相應的改進,完全克服了以上缺陷,使得ASP .NET Session成為了一個更加強大的功能。 [3] 
主要特點
Session是JAVA應用程序Hibernate進行交互時使用的主要接口,它也是持久化操作核心API
注意這裏的Session的含義,它與傳統意思上web層的HttpSession並沒有關係,Hibernate Session之於Hibernate,相當於JDBC Connection相對與JDBC。
Session對象是有生命週期的,它以Transaction對象的事務開始和結束邊界。
Session作為貫穿Hibernate的持久化管理器核心,提供了眾多的持久化的方法,如save(),update,delete,find(Hibernate 3中已經取消了此方法,)等,通過這些方法可以透明的完成對象的增刪改查(CRUD-- create read update delete),這裏所謂的透明是指,Session在讀取,創建和刪除映射的實體對象的實例時,這一系列的操作將被轉換為對數據庫表中數據的增加,修改,查詢和刪除操作。
Session有以下的特點:
1、不是線程安全的,應該避免多個線程共享同一個Session實例;
2、Session實例是輕量級的,所謂輕量級:是指他的創建和刪除不需要消耗太多資源;
3、Session對象內部有一個緩存,被稱為Hibernate第一緩存,他存放被當前工作單元中加載的對象,每個Session實例都有自己的緩存。
org.hibernate Interface Session
public interface Session extends Serializable : 是一個Java application 和Hibernate之間主要的運行時接口,這是執行持久化服務的中心API。
主要方法:
public Transaction beginTransaction() throws HibernateException:返回和當前Session對象相互聯繫的Transaction對象(表示在數據庫中重新開始一個事務)
public Transaction getTransaction():返回和當前session聯繫的Transaction對象
public Connection connection close() throws HibernateExcepton:結束當前的Session對象
public void clear() :清空Session,清除所有保存在當前Session緩存中的實體對象,終止所有正在執行的方法(eg: save(),update(),delete() .....)
public Serializable save(Object object)throws HibernateException 對當前參數指定的對象進行持久化(系統會首先賦予參數對象一個標識符OID),他相當於insert語句 後面在詳細介紹
public Connection connection() throws HibernateException 得到當前Session 中包含的Connection對象
public boolean contains(Object object):判斷參數給出的對象(持久化類)是否在當前Session的緩存中
public void evict(Object object) throws HibernateException :將參數給出的Object從當前Session對象類中刪除,使這個對象從持久態變成遊離態,這種狀態的改變不會引起對數據庫的同步
public Object load(Class theclass,Serializable id) throws HibernateException 返回第一個參數指定類對應的表中,第二個參數指定的行(第二個參數就是要取得對象的OID,他對應表中主鍵列的值)
public void update(Object object) throws HibernateException :更新一個對象到數據庫中
public void delete (Object object)throws HibernateException:從數據庫中刪除和參數指定的對象對應的記錄
public Object get(Class class,Serializable id) throws HibernateException:和load()方法一樣區別在於,如果數據庫表中沒有對應的記錄,get()方法返回null,load()方法將報異常
相關接口
Transaction接口是Hibernate的數據庫事務接口,用於管理事務,他對底層的事務作出了封裝,用户可以使用Transaction對象定義自己的對數據庫的原子操作,底層事務包括:JDBC API,JTA(Java Transaction API)。
一個Transaction對象的事務可能會包括多個對數據庫進行的操作
org.hibernate Interface Transaction
public interface Transaction
常用方法
public void commit() throws HibernateException 刷新當前的Session以及結束事務的工作,這個方法將迫使數據庫對當前的事務進行提交
public void rollback() throws HibernateException :強迫回滾當前事務
public boolean isActive() throws HibernateException:這個事務是否存活
----------------------------------------------------------------------------------------
Session:當中包含一個Connection對象
Connection c =session.getConnection();
Session的緩存用於臨時保存持久化的對象,等到一定時候,再將緩存中的對象保存到數據庫中。
應用程序事務:如果一個Session中包含有多個Transaction(數據庫事務),這些Transaction的集合稱為應用程序事務標準使用形式:
Configuration config=new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionfactory=config.buildSessionFactory();
Session session=sessionfactory.openSession();
Transaction tx=session.beginTransaction();
try
{
session.save();
tx.commit();
}
catch(Exception e)
{
if(tx!=null) tx.rollback();
}
finally
{
session.close ();
}
參考資料
  • 1.    程錦 , 李磊 , 楊誠.基於ICE中間件自定義Session機制的遠程監控系統:華東交通大學學報,2009:76-80
  • 2.    盛華.Java網絡編程實用精解:機械工業出版社,2009
  • 3.    張朝輝.WEB編程中Cookie與Session的比較分析:科技信息, 2006:44