台灣最大程式設計社群網站
線上人數
457
 
會員總數:245463
討論主題:189220
歡迎您免費加入會員
討論區列表 >> 專欄文章 >> Session 和 Cookie 的用法與差別
[]  
[我要回覆]
回應主題 加入我的關注話題 檢舉此篇討論 將提問者加入個人黑名單
Session 和 Cookie 的用法與差別
價值 : 0 QP  點閱數:3574 回應數:0

樓主

站務人員 站長
門外漢
0 1580
542 9
發送站內信

捐贈 VP 給 站務人員
管理工作階段

開發成功的 Web 應用程式的挑戰之一,便是維護使用者在應用程式的頁面之間移動時拜訪或工作階段期間的資訊。
HTTP 是一種無狀態的通訊協定,也就是說您的 Web 伺服器將頁面的每個 HTTP 要求都當作獨立要求來處理;伺服器完全不保留先前要求的認知,即使只是在現行要求之前數秒鐘提出的要求也一樣。
不具有記憶先前要求的能力,表示難以撰寫諸如線上類別目錄等的應用程式,這種應用程式可能需要追蹤使用者在各個類別目錄頁面之間切換時所選取的類別目錄項目。

ASP 提供了管理工作階段資訊問題的唯一解決方案。 使用 ASP Session 物件和伺服器產生的特殊使用者 ID,就可以建立出聰明的應用程式,它可以識別各個訪客,並蒐集應用程式稍後可用來追蹤使用者細項設定或選擇的資訊。

重要 ASP 使用 HTTP cookie 來指定使用者 ID,cookie 是儲存在使用者瀏覽器上的小檔案。 因此,若要建立用於不支援 cookie 的瀏覽器的應用程式,或者客戶可能將瀏覽器設定為拒絕 cookie,就不應使用 ASP 的工作階段管理功能。

啟動和結束工作階段

工作階段可用四種方式啟動:

新使用者要求能識別應用程式中 .asp 檔案的 URL,而且該應用程式的 Global.asa 檔案包含 Session_OnStart 程序。

使用者將值存入 Session 物件中。

當伺服器收到不包含有效的 SessionID cookie 時便會自動啟動新的工作階段。

使用者要求應用程式中的 .asp 檔案,而且應用程式的 Global.asa 檔案使用 <OBJECT> 標記來表示具有工作階段領域的物件。
請參閱使用元件和物件以獲得更多有關使用 <OBJECT> 標記來表示物件的資訊。

如果使用者在指定的時間內並未重新要求或重新整理應用程式中的頁面,就會自動結束工作階段。
此數值預設為 20 分鐘。 藉由設定 Internet Information Services 嵌入式管理單元中 [應用程式選項] 內容頁的工作階段逾時時間屬性,即可變更該應用程式的預設值。
依據 Web 應用程式和伺服器的記憶體容量來設定此值。
例如,如果預期瀏覽 Web 應用程式的使用者只在每頁逗留數分鐘,則可能要大幅減少預設的工作階段逾時時間。
太長的工作階段逾時時間會導致開啟太多工作階段,如此會過度耗用伺服器的記憶體資源。


若在指定的工作階段中,想要將逾時時間設定為比預設的應用程式逾時時間還短,則可以設定 Session 物件的 Timeout 屬性。
例如,下列指令將逾時時間設定為 5 分鐘。
<%  Session.Timeout = 5  %>

您也可以將逾時時間設定設定為大於預設值,此值由 Session Timeout 屬性來決定。

注意事項:
逾時時間只適用於具有狀態的工作階段。
在無狀態工作階段期間,Session 物件不包含內容或靜態物件。
在處理要求並在同一瀏覽器重新建立下一個要求之後,就會自動結束這種工作階段。

或者,若要故意結束工作階段,您可以使用 Session 物件的 Abandon 方法。 例如,您可以在表單中提供 [結束] 按鈕,此表單將 ACTION 參數設定為包含下列指令的 .asp 檔案的 URL。

<% Session.Abandon %>

注意事項 排定在開始 Session.Abandon 之前執行的使用者要求,將會在放棄的工作階段內容中執行。
在 Session.Abandon 完成執行之後,新進的要求就與此工作階段無關。



關於 SessionID 和 Cookie

使用者第一次在指定的應用程式中要求 .asp 檔案時。ASP 便會建立 SessionID。 SessionID 是經過複雜運算之後所獲得的數字,可唯一識別各使用者的工作階段。 在開始新工作階段時,伺服器會將 SessionID 當作 cookie 儲存在使用者的 Web 瀏覽器中。

SessionID cookie 類似儲物櫃的鑰匙,當使用者在工作階段期間與應用程式互動時,ASP 可以將使用者資訊儲存在伺服器的「儲物櫃」中。
在 HTTP 要求標題中傳輸的使用者 SessionID cookie,可讓您存取資訊,就像儲物櫃鑰匙可讓您存取儲物櫃中的內容物一樣。 每次 ASP 收到頁面的要求時,就會檢查 SessionID cookie 的 HTTP 要求標題

將 SessionID cookie 儲存在使用者的瀏覽器之後,ASP 會使用同一個 cookie 來追蹤工作階段,甚至使用者要求另一個 .asp 檔案或要求在其他應用程式中執行的 .asp 檔案也一樣。
同理,如果使用者故意放棄或讓工作階段逾時,然後要求另一個 .asp 檔案,則 ASP 仍會使用相同的 cookie 來開始新的工作階段。 只有伺服器管理員重新啟動伺服器而清除記憶體中儲存的 SessionID 設定值時,或使用者重新啟動 Web 瀏覽器時,使用者才會收到新的 SessionID cookie。

藉由重複使用 SessionID cookie,ASP 使傳送至瀏覽器的 cookie 數目變得最少。
此外,如果決定您的 ASP 應用程式不要求工作階段管理,則可以避免 ASP 追蹤工作階段和傳送 SessionID cookies 給使用者。

在下列狀況下,ASP 不會傳送工作階段 cookie:

如果應用程式停用工作階段狀態。

如果 ASP 網頁定義為無工作階段,也就是頁面中包含

<%@ EnableSessionState=False %>

標記。 若需其他資訊,請參閱無工作階段的 ASP 網頁。

您應該也注意到,SessionID cookie 並未提供多次拜訪 Web 站台時追蹤使用者的永久方法。 因此儲存在伺服器記憶體中的 SessionID 資訊很容易失去。 若要追蹤長期拜訪 Web 應用程式的使用者,就必須在使用者的 Web 瀏覽器中儲存特殊的 cookie,並將此 cookie 資訊儲存至資料庫中,以建立使用者識別碼。 若需其他資訊,請參閱使用 Cookie。

儲存和移除 Session 物件中的資料

Session 物件提供動態的聯合陣列,可讓您將資訊存入其中。 您可以將純量變數和物件變數存入 Session 物件中。

若要將變數存入 Session 物件,請指定數值至 Session 物件的具名項目中。 例如,下列指令會將兩個新變數存入 Session 物件中:
<%

Session("FirstName") = "Jeff"

Session("LastName") = "Smith"

%>

若要擷取 Session 物件的資訊,請存取具名項目。 例如,若要顯示 Session("FirstName") 目前的值:

Welcome <%= Session("FirstName") %>

您可以將使用者的喜好設定儲存在 Session 物件中,然後存取該喜好設定以決定要傳送給使用者的頁面。 例如,您可在應用程式的第一頁讓使用者指定純文字內容,然後將這個選擇套用至使用者在此應用程式中所拜訪的所有後續頁面上。

<% If Session("ScreenResolution") = "Low" Then %>

這是文字版本的頁面。

<% Else %>

這是多媒體版本的頁面。

<% End If %>

雖然會影響到伺服器的效能,但您也可以將物件實例存入 Session 物件中。 若需其他資訊,請參閱設定物件領域。

有時候您可能希望刪除儲存在 Session 物件中的項目。
例如,對拜訪線上零售商店的使用者而言,變更心意、放棄採購項目清單和決定完全不同的選擇都是司空見慣的事。
在這種狀況下,刪除不適當的值就能很方便地更新 Session 物件。


Session 物件的 Contents 集合包含工作階段中已經儲存的所有變數 (亦即不是使用 HTML <OBJECT> 標記儲存的變數)。
利用 Contents 集合的 Remove 方法,可以選擇性地移除工作階段狀態加入的變數參照。
下列指令說明如何使用 Remove 方法從 Session 物件清除項目,此例為移除使用者帳戶資訊:

<%

If Session.Contents("Purchamnt") <= 75 then

Session.Contents.Remove("Discount")

End If

%>

如果需要的話,也可以使用 Contents 集合的 RemoveAll 方法完全移除工作階段中所儲存的變數:

Session.Content.RemoveAll()

使用 Remove 方法時,可以選擇依名稱或索引來刪除項目。 下列指令示範如何循環變更儲存在 Session 物件中的值,然後有條件地依索引來移除數值:

<%

For Each intQuote in Session.Contents

If Session.Contents(intQuote) < 200 Then

Session.Contents.Remove(intQuote)

End If

Next

%>

管理橫跨多個伺服器的工作階段

ASP 工作階段資訊儲存在 Web 伺服器中。 瀏覽器必須向同一部 Web 伺服器的頁面要求存取工作階段資訊的指令。
在 Web 伺服器的叢集 (許多 Web 伺服器在此分擔回應使用者要求的責任) 上,使用者的要求並不會都送到同一部伺服器。
反而特殊的軟體會將站台 URL 的所有要求配送至可用的伺服器,此程序稱為負載平衡。
負載平衡使得難以讓工作階段資訊保留在 Web 伺服器的叢集上。

若要在負載平衡的站台中使用 ASP 工作階段管理,您必須確定使用者工作階段中的所有要求都導引至同一部 Web 伺服器。
其中一個辦法是撰寫 Session_OnStart 程序,此程序使用 Response 物件將瀏覽器重新導引至執行使用者工作階段的特定 Web 伺服器。 如果應用程式頁面中的所有連結都是相對連結,則未來對於頁面的要求都會導引至同一部伺服器。

例如,使用者可用要求站台的一般 URL 來存取應用程式: http://www.microsoft.com。 負載平衡程式會將要求轉送至指定的伺服器,例如 server3.microsoft.com。 ASP 會在該伺服器建立新的使用者工作階段。
在 Session_OnStart 程序中,會將瀏覽器重新轉送至指定的伺服器:

<% Response.Redirect("http://server3.microsoft.com/webapps/firstpage.asp") %>

瀏覽器會要求指定的頁面,而所有後續的要求都會轉送至同一部伺服器,只要原始 URL 未參照指定的伺服器名稱。


使用 Cookie

Cookie 是 Web 伺服器內嵌在使用者 Web 瀏覽器中用來識別使用者的 token。
下次相同的瀏覽器要求頁面時,就會傳送從 Web 伺服器收到的 cookie。 Cookie 可讓一組資訊與使用者有所關聯。
ASP 指令可以取得和設定 cookie 的值,只要利用 Response 和 Request 物件的 Cookie 集合即可。

設定 Cookie

若要設定 cookie 的值,請使用 Response.Cookies。如果 cookie 不存在,Response.Cookies 就會建立新的 cookie。
例如,若要將稱為 ("VisitorID") 的 cookie 中相關的值 ("49") 傳送至瀏覽器,請使用下列指令,這個指令必須出現在 Web 網頁的 <HTML> 標記之前:
<% Response.Cookies("VisitorID") = 49 %>

若要讓 cookie 只用於目前使用者工作階段,則您必須做的事只有傳送 cookie 至瀏覽器。不過,若在使用者停止和重新啟動瀏覽器之後,還要能識別使用者,就必須強制瀏覽器將 cookie 儲存在用戶端電腦硬碟的檔案中。 若要儲存 cookie,請使用 Response.Cookies 的 Expires 屬性,並將日期設定為未來的某個日子:

<%

Response.Cookies("VisitorID") = 49

Response.Cookies("VisitorID").Expires = "December 31, 2001"

%>

一個 Cookie 可以有好幾個值;這種 cookie 稱為索引 cookie。 索引 cookie 的值指定為識別碼;您可以設定特殊的 cookie 鍵值。 例如:

<% Response.Cookies("VisitorID")("49") = "Travel" %>

如果現有的 cookie 具有鍵值,但 Response.Cookies 並未指定識別碼名稱,則會刪除現有的鍵值。 同理,如果現有 cookie 不具有鍵值,但 Response.Cookies 指定其識別碼名稱,則會刪除 cookie 的目前值,然後建立新的鍵值組。

取得 Cookie

若要取得 cookie 的值,請使用 Request.Cookies 集合。例如,如果使用者的 HTTP 要求設定 VisitorID=49,則下列陳述式會擷取值 49:
<%= Request.Cookies("VisitorID") %>

同理,若要從索引 cookie 擷取鍵值,請使用識別碼名稱。 例如,如果使用者的瀏覽器在 HTTP 要求標題中傳送下列資訊:

Cookie: VisitorID=49=Travel

下列陳述式就會傳回值 Travel:
<%= Request.Cookies("VisitorID")("49") %>

設定 Cookie 路徑

ASP 儲存在使用者 Web 瀏覽器的每個 cookie 都包含了路徑資訊。
當瀏覽器要求儲存在 cookie 指定路徑中的檔案時,瀏覽器就會自動將 cookie 轉送至伺服器。
在預設情況下,cookie 路徑會對應於包含最先建立此 cookie 的 .asp 檔案的應用程式名稱。
例如,如果儲存在應用程式中稱為 UserApplication 的 .asp 檔案建立 cookie,則每次使用者的 Web 瀏覽器擷取該應用程式中的任何檔案時,除了包含路徑 /UserApplication 的任何其他 cookie 之外,瀏覽器還會轉送此 cookie。

若要指定 cookie 路徑而不是預設的應用程式路徑,則可以使用 ASP Response.Cookies 集合的 Path 屬性。
例如,下列的指令會將路徑 SalesApp/Customer/Profiles/ 指定至稱為 Purchases 的 cookie:

<%

Response.Cookies("Purchases") = "12"

Response.Cookies("Purchases").Expires = "January 1, 2001"

Response.Cookies("Purchases").Path = "/SalesApp/Customer/Profiles/"

%>

每當包含 Purchases cookie 的 Web 瀏覽器要求路徑 /SalesApp/Customer/Profiles/ 或其任何子目錄中的檔案時,瀏覽器就會轉送 cookie 至伺服器。

許多 Web 瀏覽器都會保留 cookie 路徑的大小寫,包括 Microsoft Internet Explorer 4.0 版或更新版本,以及 Netscape 瀏覽器。 這表示如果要求的檔案路徑大小寫與儲存的 cookie 路徑大小寫不同,瀏覽器就不會傳送 cookie 至伺服器。
例如,對 ASP 而言,虛擬目錄 /TRAVEL 與 /travel 是指相同的 ASP 應用程式,但對保留 URL 大小寫的瀏覽器而言,/TRAVEL 和 /travel 是兩個不同的應用程式。 確定所有 .asp 檔案的 URL 都具有相同的大小寫,以確定使用者的瀏覽器轉送儲存的 cookie。

您可以使用下列陳述式來設定 cookie 路徑,讓使用者的 Web 瀏覽器每次要求伺服器的檔案時都會轉送 cookie,而與應用程式或路徑無關:

Response.Cookies("Purchases").Path = "/"

不過,要注意轉送 cookie 至伺服器而不區分應用程式,如果 cookie 包含不該在指定的應用程式以外來存取的敏感資訊,則會造成潛在的安全問題。

不使用 Cookie 保留狀態

並非所有的瀏覽器都支援 cookie。 即使使用支援 cookie 的瀏覽器,部分使用者仍比較喜歡關閉 cookie 支援。 如果應用程式需要回應不支援 cookie 的瀏覽器,則不能使用 ASP 工作階段管理。

此時必須自行撰寫在應用程式的頁面之間傳送資訊的機制。 一般而言有兩種做法:

將參數加入 URL 的查詢字串中。 例如:

http://MyServer/MyApp/start.asp?name=Jeff

不過,如果以 GET 方法來提送表單,部分瀏覽器會捨棄查詢字串中傳送的任何明確參數。

在表單加入隱藏值。 例如,下列 HTML 表單包含隱藏的控制,此控制不會出現在實際的表單中,在使用者的 Web 瀏覽器上也看不見。 此表單除了傳送使用者提供的資訊之外,還使用 HTTP POST 方法傳送使用者的識別值。

<FORM METHOD="POST" ACTION="/scripts/inform.asp">

<INPUT TYPE="text" NAME="city" VALUE="">

<INPUT TYPE="text" NAME="country" VALUE ="">

<INPUT TYPE="hidden" NAME="userid" VALUE= <%= UserIDNum(i) %>

<INPUT TYPE="submit" VALUE="Enter">

此方法要求傳送使用者資訊的所有連結目標都以 HTML 表單來編碼。

若未使用 ASP 工作階段管理,應該關閉應用程式的工作階段支援。
在啟用工作階段時,ASP 會傳送 SessionID cookie 給要求頁面的每個瀏覽器。
若要關閉工作階段支援,請清除 Internet Information Services 嵌入式管理單元 [應用程式選項] 內容頁中的 [啟用作業狀態] 核取方塊。


無工作階段的 ASP 網頁

您也可以使用 ASP 來建立無工作階段的頁面,此頁面可以在需要時才建立工作階段。

無工作階段頁面並不會執行下列各項:

執行 Session_OnStart 程序。

傳送 sessionID cookie。

建立 Session 物件。

存取內建的 Session 物件或使用 <OBJECT> 標記建立的工作階段領域物件。

與其他工作階段要求連續執行。

若要將 .asp 檔案設定為無工作階段,請使用下列指令:

<%@ EnableSessionState=False %>

您應該將此指令放在 .asp 檔案的第一行,在任何其他指令之前。 忽略此標記時,預設會啟用工作階段追蹤。


無工作階段的 ASP 網頁通常可以藉由消除潛在的耗時工作階段活動來改善伺服器的回應速度。
例如,考慮下列包含兩個 HTML 框架的 ASP 網頁: 框架 1 和 2 都在同一個框架組中。
框架 1 包含執行複雜指令的 .asp 檔案,而框架 2 包含比較簡單的 .asp 檔案。
因為 ASP 依序或連續執行工作階段要求,在框架 1 的指令完成執行之前,就無法看到框架 2 的內容。
不過,如果使框架 1 的 .asp 檔案為無工作階段,則 ASP 要求就不再為連續,瀏覽器可以在框架 1 的內容完成執行之前,就先提送框架 2 的內容。

很不幸地,處理不同框架的多重要求的方法與使用者 Web 瀏覽器的設定有很大的關係。 某些 Web 瀏覽器可能依序處理要求,而不管 .asp 檔案中的無工作階段設定。
本篇文章發表於2001-01-15 00:00
別忘捐VP感謝幫助你的人 新手會員瞧一瞧
目前尚無任何回覆
   

回覆
如要回應,請先登入.