許多開發人員把應用程式傳送到Web之前從來沒考慮狀態的概念。正如前面說過的,Web是一個無狀態的環境。因此應該探討一下狀態是什麼,瞭解能夠避免產生問題的方法。
狀態的準確定義
在單使用者程式中,建立一個可執行檔應用程式時,例如使用VB建立一個.exe檔案,可以聲明一個全域(或Public)變數,然後在代碼中任何地方可對其進行訪問。在應用程式啟動並執行所有時刻,時刻值一直是有效,並且是可訪問的。
對於一個傳統的客戶機/伺服器解決方案,例如一個基於客戶機的應用程式對一個基於伺服器的資料庫引擎進行訪問的系統,每個用戶端建立了一個與伺服器和資料庫應用程式的串連。這種串連通常是通過驗證使用者的方法來建立的。
驗證過程是典型的識別使用者身份的過程,通過一個使用者名稱和口令組合來證明是否為合法的使用者。
一旦通過驗證,在用戶端和基於伺服器的應用程式之間就建立了串連,該串連在使用者使用該應用程式的所有時間內一直保持有效。當使用者註冊到酵Windows 2000伺服器上時,這一切便會發生。無論何時,管理員使用“Active Directory Users and Computers”公用程式(單擊“Start”菜單的“Administrative Tools”選項中的“Directory Management”項)都可以觀察到活動的使用者串連。這個過程在許多系統中都相同,例如Microsoft sql server。
這種永久的串連意味著:當使用者發送指令或請求到伺服器上時,伺服器會很容易地識別每個使用者。同樣伺服器的響應或任何其他使用者的資訊也能直接返回使用者。要進一步指出的是伺服器可以比較容易地儲存與每個客戶相關的值和資訊,並在需要的時候提供給相應的客戶。當然,伺服器應用程式能夠擁有主全域變數,以便於使用者在需要的時候進行訪問。
這種識別每個用戶端的請求並在記憶體中儲存相關使用者的值的能力構成狀態。可以認為狀態代表應用程式的值、環境以及使用者的內部變數,並貫穿於應用程式和使用者串連的整個過程。
狀態的重要性
如果打算建立與使用者進行互動的基於Web網站的應用程式,而不是僅顯示獨立頁面的Web網站,必須能夠為每個使用者提供獨立的狀態。這可能只是記住他們的名字,也可能要為每個使用者儲存物件引用或不同的記錄集。如果不能這樣做,ASP網頁就不能做更多的事情,因為該頁面執行完成時,頁面中的變數和其他相關資料都破壞了。錄使用者請求下一個頁面時,這個頁面提供的所有資訊將全部失去。
因此,需要找到一種方法,儲存每個訪問者的狀態。能夠儲存對所有使用者而言的全域值是非常重要。例如,一個Web風格的訪問或頁面點擊計數器,它不為每個使用者提供自己的計數器,使用者們通常想要看到訪問者的總數,而不僅僅是他們自己訪問的次數。訪問者的數目需要與應用程式級狀態一起儲存,而不是與使用者級狀態一起儲存。
這不是一個剛出現的問題,自從商用網站佔據了Web,就已經存在,甚至更早些。所以已有許多在Web上儲存狀態的傳統的解決方案。Web網站管理員想要瞭解訪問者以前是否曾訪問過他們的網站,如果訪問過,訪問過多少次?還定期訪問其他什麼網站等。這樣可以更好地制定其廣告目標。所有這些都要求一種方法來儲存有關使用者在訪問時所產生的網頁請求或每次訪問間的資訊。
在Web上建立狀態
在頁面請求和網站訪問之間提供狀態常用的方法是通過cookie。我們在前面的章節中已經看到,如何在用戶端的電腦中存放相應的值,這些值與每個頁面請求一起發送給對此cookie有效域。通過用ASP檢查和更新cookie,在某種程度上能夠保持一個狀態。可以使用所包含的資訊來識別使用者,然後把使用者串連到一個已儲存相應值的集合。
例如,可以檢測一個使用者請求是否包含一個網站指定的cookie。如果不包含,則為該使用者指派一個某種類型的標識,指明一個數量,並儲存在帶有一個長有效期間的cookie中。以後該使用者對這個網站的每一次訪問,都能夠檢測到cookie並更新所包含的資訊。同時可以收集有關訪問的次數和期間的資料,並儲存在伺服器上,以備將來使用。
但是,如果使用者轉移到另一個電腦,或刪除了cookie,或者他們的瀏覽器拒絕接收發送給他們的cookie,會發生什麼事情呢?在這種情況下,不能維持狀態,因為下一次不能識別他們現在,Web上有許多cookie,大多數人會接受它們,而不加理會。如果開啟瀏覽器中的“Warn before accepting cookies”選項,接著漫遊幾個大的網站,你就會明白其中的含意。
1. 匿名訪問者與授權的訪問者
如果認為cookie是一個有點草率的解決方案,可以使用更直接的方法。許多網站採用的一種方法是,在訪問者點擊一個網站時,或者點擊一個要求驗證身份的頁面時,彈出一個進行登入的對話方塊。訪問者首先必須進行註冊,獲得一個某種類型的使用者名稱/口令的組合,才能允許訪問相應的網站或頁面。
為了證實訪問者是一個已知的並且合法的使用者,在訪問者的電腦上放置的一個cookie,它或者儲存註冊的詳細資料,或者是一把表明已驗證過身份的“鑰匙(key)”。同時,訪問者的詳細資料永久地儲存在伺服器上,準備再次訪問時使用。如果訪問者的瀏覽器中有了這樣一個cookie,他就可以自由地訪問該網站,因為已經驗證過了。
如果cookie沒有有效期間限(Expires),cookie的值在關閉瀏覽器時自動消失,在下一次訪問時必須重新註冊和再次驗證。當然,如果拒絕接收cookie或刪除了cookie,就只能再次得到註冊對話方塊。這樣的話,如果不被識別,就不能訪問該網站。
通過強制使用者就像註冊到自己的網路一樣註冊到Web伺服器,Windows 2000整體安全效能為IIS提供更強和更安全的驗證功能。但是,這隻能與Internet Explorer 3.0和之上版本的瀏覽器一起工作。IIS也可以使用BASIC驗證允許非Microsoft瀏覽器註冊Web伺服器。
2. 不再有匿名訪問者
在IIS Web伺服器上使用ASP時,除非使用者離開該網站到另一個網站或者關閉了瀏覽器,否則能在當前會話中跟蹤使用者。在本章的後面,將看到如何使用這個功能來標識一個訪問者、儲存使用者的本地資訊和提供狀態。下面與已經討論過的解決方案相比較,討論其工作方式。
ASP和IIS共同提出了一個使用者會話的概念,通過ASP Session對象進行互動。在每個訪問者第一次訪問伺服器上的一個ASP網頁時,為他建立一個新的並且獨立的會話對象,分配給該會話一個會話標識號,並把包含工作階段識別項的特殊加密版本的一個cookie發送給客戶。
cookie的路徑(參看前面的章節有關cookie屬性的描述)設定為運行在伺服器上的ASP應用程式的根路徑。這很可能上預設的Web網站的根目錄(即“/”),但也可能會是另外一個值(稍後會看到)。在cookie中沒有提供Expires值,所以當瀏覽器關閉時,cookie值也就消失。
每當這個使用者訪問這個ASP網頁,ASP都會尋找這個cookie。命名為ASPSESSIONIDxxxxxxxx,其中每個x是一個字母字元。從第2章圖2-7所示的ServerVariables集合,能夠在HTTP前序中看到它。
但是,這個cookie不會出現在 Request.Cookies或Response.Cookies集合中,ASP把它隱藏起來,但仍儲存在瀏覽器上。對於每個ASP網頁請求,ASP都要查看該值。這個cookie包含的值,指明了這個使用者的會話。因此,相應的Session對象(該對象在記憶體中已被處理,並且一直包含所有在前一頁面請求過程中進行操作的值)的內容可以移交給ASP網頁中的指令碼。
當然,如前所述,如果客戶瀏覽器不接收或不支援這些cookie,這個處理將失敗。在這種情況下,不能建立ASP會話,對這個訪問者的狀態也不進行自動維護。