關於Session值丟失問題

xiangchengboy發表於2010-07-20

引言:最近不少網友都有這樣的疑問,就是當我們在一個網頁間設定了一個session變數後,到另一個網頁,卻消失了。這
是什麼樣的原因呢。如果你詳細的讀完本文,相信能給你一個完整的答覆!

 

一:前言--關於web應用程式

       我們今天所討論的web 應用程式是指由Windows NT Option Pack 提供的一個建立 Internet 或Intranet的 Web應用程式的平臺。而Web 應用程式可以作為一組 Web 頁交付使用,它們向封裝了事務邏輯並提供訪問儲存重要商業資訊的資料庫應用程式和 ActiveX 元件提供使用者介面。也就是我們使用的asp程式。
       建立應用程式時,必須用 Internet 服務管理器在 Web 站點中指定應用程式的啟動點目錄。在發現其他啟動點之前,Web 站點某啟動點目錄下的每個檔案和目錄被視為是應用程式的一部分。因此,可以使用目錄邊界定義應用程式的範圍。
        基於 ASP 的應用程式是 ASP 頁和 ActiveX 元件的集合。當使用者定義應用程式時,將使用 IIS指定使用者的 Web 站點中應用程式啟動點的目錄。在使用者的 Web 站點中每個位於啟動點目錄下的檔案和資料夾都被認為是應用程式的一部分,直到發現另外的啟動點目錄為止。這樣,使用者就可以使用目錄作為邊界定義應用程式的作用域。每個 Web 站點可以有多個應用程式,而每個應用程式的配置都可以不同。

二:web應用程式的範圍

        正如上面的定義所提到的。我們將一個web應用程式,如:購物程式,新聞程式,聊天程式......等這樣一些我們開發的asp頁面單獨集中來成為一個web應用程式。結合例項來說,如我們將一個購物程式的所有頁面(如:註冊頁面,購物車,收銀臺,訂單頁面,商品頁面)統一起來,統稱為一個web購物程式,它的應用程式範圍就是從購物開始購物結束所涉及到的所有頁面。而在iis中,系統須將其分配到一個虛擬目錄中去,而該虛擬目錄的所有頁面,及其子目錄就是其購物程式的物理範圍。如下表所示。
*shop—index.asp
—buy.asp
+catalog—list.asp
+customer—a.asp
—b.asp
其中*號,代表的是一個虛擬目錄,+代表的是其中的子目錄。所以,整個上面的所有頁面構成了一個web應用程式。但是,也可以在一個虛擬目錄下建立另一個應用程式。如下表
*shop—index.asp
—buy.asp
*book—book.asp
+catalog—list.asp
+customer—a.asp
—b.asp
這樣,shop下的index.asp,list.asp,a.asp等屬於一個應用程式,而book下的book.asp則不屬於shop,他是一個新的web應用程式。

三:web應用程式範圍的設定與應用

        如果你的開發環境是Visual InterDev6.0,那麼,應用程式的設定幾乎不用你費心去考慮,一切有VI6來給你設定好了,並在IIS中自動建立了虛擬目錄,但如果是其他的話,你可能需要在IIS中自己去設定他。具體步驟如下:
建立應用程式
1--在“Internet 服務管理器”中,選擇作為應用程式啟動點的目錄。可以將 Web 站點的主目錄指定為 應用程
序的啟動點。 
2--開啟該目錄的屬性頁,然後單擊“主目錄”、“虛擬目錄”或“目錄”選項卡。 
3--在“名稱”文字框中,為應用程式鍵入名稱。'當然,應用程式的名稱也不是必要的。但推薦設定。
4--單擊“建立”按鈕。
        此後,你就可以將你的web應用程式目錄對映到該目錄下即可。
        明白以上的基本定義,對我們網路開發人員十分必要,應為,正是由於有了一個web應用程式的範圍,才可以使web應用程式能夠在應用程式的檔案間共享資訊,例如,ASP 應用程式可在其網頁間共享環境流、會話狀態和變數設定。也就是我們經常使用的session,application物件等。應為只有規定了一個應用程式及其範圍,session,application等物件才有意義。

四:session變數“丟失”的問題

        談到了那麼多的概念,終於可以說道實質性的問題了,session物件是web應用程式中最重要的對像之一,正是它的存在,使得我們可以在跨網頁間傳送資料,分辨不同使用者成為可能。我們只要將變數制定給session即可實現。這一過程即session("temp")=temp即可。但最近不少網友都有這樣的疑問,就是當我們在一個網頁間設定了一個session變數後,到另一個網頁,卻消失了。這是什麼樣的原因呢。
根據上面的概念,我們可以將其原因,和處理辦法總結如下。
1:asp網頁跨了多個web應用程式:
        這個原因就是你的另一個網頁可能是另一個web應用程式。以前,一些資料過分的強調了會話變數的單一性,好像一個使用者連線到一個web主機之後,只可能建立一個會話變數,這是不對的,分辨會話變數的依據正是我們上面所提到的web應用程式範圍,而不是單獨根據使用者而建立的,你可以試一試下面的一段程式碼。
test.asp
<% @ language=vbscript %>
<%
session("temp")="temp"
Response.Write session.SessionID 'sessionID用來分辨一個應用程式間的單獨客戶。
%>

        將test.asp分別拷貝到兩個不同的虛擬目錄下。你就可以看到,他是兩個不同的值了。所以,可能你的網頁跨了不同的應用程式。當然,這種情況對於初學者可能碰到,對於有經驗的人可能犯的是這樣的錯誤,即他們本身為一個根目錄,但在制定虛擬目錄時將其子目錄又設為一個虛擬目錄了,就如同我們上面提到的第二個表結構一樣。這樣他同樣成為了兩個不同的web應用程式。也就不難解釋為什麼會出錯了。

2:可能是啟動了多個同一應用程式。
        第一種情況很好發現,也容易改正,但這第二種情況就不容易發現,也較難改正。這裡我們引入一個另一個的概念。多個同一應用程式共存,(好長呀,關鍵是微軟的概念我忘了,這個是我自己起的。呵呵!),它的意思從這個定義上很好理解,就是對於同一個應用程式。同一時間可以在記憶體中存在多個。如我們常見的acdsee.exe,你可以通過點選啟動多個acdsee.exe。而另外一種則不能,我們就不說它的定義了(如果說的話,就是相同應用程式不共存,呵呵!)在同一時間內,如果已經啟動了一個應用程式,則不能再啟動相同的應用的應用程式了。如foxmail.exe,當你啟動了一個foxmail.exe後,就只可能在記憶體中存在一個foxmail.如果你在啟動,則不會再開一個foxmail視窗了。
        而我們的ie屬於前者,你可以通過點選ie,啟動多個ie應用程式。此時,我們做下面另一個測試。你將上面的程式碼test.asp放入一個虛擬目錄中。然後,你點選ie啟動(注意:是通過點選Ie啟動,不是按CTRL+N,也不是在一個ie視窗點選檔案,重新開啟一個視窗)此時,你可以發現,他們雖然是同一個地址,同一個使用者,但sessionID還是不同的,當然,你還可以建另一個檔案。如
test2.asp
<% @ language=vbscript %>
<%
response.write session("temp")
%>
        這時,你在另一個ie視窗下,你就會發現session("temp")為空,也就是說,我們剛才明明在test.asp中附了值,而且test2.asp和test.asp在同一虛擬目錄下,但session("temp")卻丟失了。原來,相對於相同的asp應用程式。不同的ie相對的卻是不同的asp應用程式。(有點像繞口令難懂是吧。)不過,我們已經明白了它的起因,相信不難解決他。
        這裡還要注意的是,我們剛才一再提到的是通過點選Ie,而不是通過按CTRL+N,也不是在一個ie視窗點選檔案,重新開啟一個視窗,這裡要說明的是如果你通過在一個ie視窗開啟的視窗,它屬於派生視窗,而不是共生視窗,就是說,此時的另一個視窗屬於和其上一個視窗是繼承關係,屬於同一個應用程式範圍。
3:連線不當
        其實,大部分的網友碰到的問題是通過點選頁面中的連線新開視窗而發現session變數丟失的。他同按ctrl+N新開視窗的意義相同。但此時為什麼會出問題呢?我們來分析一下它的連線方式。可能為<a href="xx.asp" traget=_blank>click 
me </a>通過這樣點選的連線同ctrl+n 是相同的,應該不會出問題。還有一種連線式通過指令碼控制的如
window.open "xx.asp","name","toolbar=no"這樣的程式碼,他就可能發生這樣的問題。如果通過點選ie開了多個共生視窗(許多網友為了節省時間,他們喜歡開多個視窗。比如我。)。就是他可能在新開的視窗中如果含有相同的name的視窗。
則此時,就可能發生連線不當導致session丟失,其實,原因還是通第二種一樣。還有一種更極端的方式開新視窗,通過用
document.write 在一個指令碼中動態寫出新的頁面,而該頁面的url是不存在的,這樣就更可能出問題了,應為session正是通過url,http來追蹤的。所以如果其頁面地址是動態的話。則session就根本無法追蹤了。

        相信通過以上例子的分析,可能會解釋你在應用session中出現的大部分問題。但不是全部(如過你禁用cookie的話,呵呵!)但是,如果你將以上的概念都弄懂,則可以解決你在應用session中出現的所用問題了。

相關文章