Session和Cookie的區別
具體來說cookie機制採用的是在客戶端保持狀態的方案,而session機制採用的是在服務器端保持狀態的方案。同時我們也看到,由於採用服務器端保持狀態的方案在客戶端也需要保存一個標識,所以session機制可能需要藉助於cookie機制來達到保存標識的目的,但實際上它還有其他選擇。
cookie機制。正統的cookie分發是通過擴展HTTP協議來實現的,服務器通過在HTTP的響應頭中加上一行特殊的指示以提示瀏覽器按照指示生成相應的cookie。然而純粹的客戶端腳本如JavaScript或者VBScript也可以生成cookie。而cookie的使用是由瀏覽器按照一定的原則在後台自動發送給服務器的。瀏覽器檢查所有存儲的cookie,如果某個cookie所聲明的作用範圍大於等於將要請求的資源所在的位置,則把該cookie附在請求資源的HTTP請求頭上發送給服務器。
cookie的內容主要包括:名字,值,過期時間,路徑和域。路徑與域一起構成cookie的作用範圍。若不設置過期時間,則表示這個cookie的生命期為瀏覽器會話期間,關閉瀏覽器窗口,cookie就消失。這種生命期為瀏覽器會話期的cookie被稱為會話cookie。會話cookie一般不存儲在硬盤上而是保存在內存裡,當然這種行為並不是規範規定的。若設置了過期時間,瀏覽器就會把cookie保存到硬盤上,關閉後再次打開瀏覽器,這些cookie仍然有效直到超過設定的過期時間。存儲在硬盤上的cookie可以在不同的瀏覽器進程間共享,比如兩個IE窗口。而對於保存在內存裡的cookie,不同的瀏覽器有不同的處理方式
session機制。 session機制是一種服務器端的機制,服務器使用一種類似於散列表的結構(也可能就是使用散列表)來保存信息。
當程序需要為某個客戶端的請求創建一個session時,服務器首先檢查這個客戶端的請求裡是否已包含了一個session標識(稱為session id),如果已包含則說明以前已經為此客戶端創建過session ,服務器就按照session id把這個session檢索出來使用(檢索不到,會新建一個),如果客戶端請求不包含session id,則為此客戶端創建一個session並且生成一個與此session相關聯的session id ,session id的值應該是一個既不會重複,又不容易被找到規律以仿造的字符串,這個session id將被在本次響應中返回給客戶端保存。
保存這個session id的方式可以採用cookie,這樣在交互過程中瀏覽器可以自動的按照規則把這個標識發揮給服務器。一般這個cookie的名字都是類似於SEEESIONID。但cookie可以被人為的禁止,則必須有其他機制以便在cookie被禁止時仍然能夠把session id傳遞回服務器。
經常被使用的一種技術叫做URL重寫,就是把session id直接附加在URL路徑的後面。還有一種技術叫做表單隱藏字段。就是服務器會自動修改表單,添加一個隱藏字段,以便在表單提交時能夠把session id傳遞回服務器。比如:
<form name="testform" action="/xxx">
<input type="hidden" name="jsessionid" value="ByOK3vjFD75aPnrF7C2HmdnV6QZcEbzWoWiBYEnLerjQ99zWpBng!-145788764">
<input type="text">
</form>
實際上這種技術可以簡單的用對action應用URL重寫來代替。
Session優缺點以及推薦解決方案
Session有哪些缺點
①當mode="InProc"時,也就是默認設置時,容易丟失數據,為什麼?因為網站會因為各種原因重啟。
② 當mode="InProc"時,Session保存的東西越多,就越佔用服務器內存,對於用戶在線人數較多的網站,服務器的內存壓力會比較大。
③當mode="InProc"時,程序的擴展性會受到影響,原因很簡單:服務器的內存不能在多台服務器間共享。
④雖然Session可以支持擴展性,也就是設置mode="SQLServer"或者mode="StateServer",但這種方式下,還是有缺點:在每次請求時,也不管你用不用會話數據,都為你準備好,這其實是浪費資源的。
⑤ 如果你沒有關閉Session,SessionStateModule就一直在工作中,尤其是全採用默認設置時,會對每個請求執行一系列的調用。浪費資源。
⑥並發問題,前面有解釋,也有示例。
⑦當你使用無Cookie 會話時,為了安全,Session默認會使用重新生成已過期的會話標識符的策略,此時,如果通過使用HTTP POST 方法發起已使用已過期會話ID 發起的請求,將丟失發送的所有數據。這是因為ASP.NET 會執行重定向,以確保瀏覽器在URL 中具有新的會話標識符。
不使用Session的替代方法
對於前面我列出的Session的一些缺點,如果您認為你有些是不能接受的,那麼,可以參考一下我提出的替代解決方法。
①如果需要在一個頁面的前後調用過程中維持一些簡單的數據,可以使用<input type="hidden" />元素來保存這些數據。
②您希望在整個網站都能共享一些會話數據,就像mode="InProc"那樣。此時,我們可以使用Cookie與Cache相結合做法,自行控制會話數據的保存與加載。具體做法也簡單:為請求分配置一個Key(有就忽略),然後用這個Key去訪問Cache,以完成保存與加載的邏輯。如果要使用的會話數據數量不止一個,可以自定義一個類型或者使用一個諸如Dictionary, HashTable 這樣的集合來保存它們。很簡單吧,基本上這種方式就是與mode="InProc"差不多了。只是沒有鎖定問題,因此也就沒有並發問題。
③ 如果您想實現mode="StateServer"類似的效果,那麼可以考慮使用memcached這類技術,或者自己寫個簡單的服務,在內部使用一個或者多個Dictionary, HashTable來保存數據即可。這樣我們可以更精確的控制讀寫時機。這種方法也需要使用Cookie保存會話ID。
4. 如果您想實現mode="SQLServer"類似的效果,那麼可以考慮使用mongodb這類技術,同樣我們可以更精確的控制讀寫時機。這種方法也需要使用Cookie保存會話ID。如果您沒用使用過mongodb
從前面三種替代方法來看,如果不使用Session,那麼Cookie就是必需的。其實Cookie本身就是設計用來維持會話狀態的。只是它不適合保存過大的數據而已,因此,用它保存會話ID這樣的數據,可以說是很恰當的。事實上,Session就是這樣做的。
推薦方法:為了保持網站程序有較好的擴展性,且不需要保存過大的會話數據,那麼,直接使用Cookie將是最好的選擇。
由於Cookie保存在瀏覽器,且不安全,所以建議只保存諸如:id, key 之類的簡單數據,需要其它的會話數據時再根據這些id, Key去獲取。
Cookie解析
先了解一下Cookie工作原理以及保存方式:
Cookie通過HTTP Headers從服務器端返回到瀏覽器上。首先,服務器端在響應中利用Set-Cookie header來創建一個Cookie ,然後,瀏覽器在它的請求中通過Cookie header包含這個已經創建的Cookie,並且反它返回至服務器,從而完成瀏覽器的論證。
Internet Explorer 將站點的Cookie 保存在文件名格式為<user>@<domain>.txt 的文件中,其中<user> 是您的帳戶名。例如,如果您的名稱為user,您訪問的站點為www.nowamagic.net,那麼該站點的Cookie 將保存在名為user@nowamagic.net.txt 的文件中。 (該文件名可能包含一個順序的編號,如user@nowamagic.net [1].txt。) Cookie 文本文件是與用戶相關的,所以會按照帳戶分別保存。
一個Cookie 會佔用大約50 個字符的基本空間開銷(用於保存有效期信息等),再加上其中保存的值的長度,其總和接近4K 的限制。大多數瀏覽器只允許每個站點保存20 個Cookie 。
cookie運行解決方案
1、多數的服務器會使用session複製的方法:當session的值被改變時,將它複製到其它機器上。這個方案又有兩種具體的實現,一種是廣播的方式,缺點:當訪問量增大的時候,帶寬增大,而且隨著機器增加,網絡負擔成指數級上升,不具備高度可擴展性;另一種是TCP-ring的方式,也就是把集群中所有的服務器看成一個環,A->B->C->D->A,首尾相接,缺點:一是配置複雜;二是每增添/減少一台機器時,ring都需要重新調整,這將成為性能瓶頸;三是要求前端的Load Balancer具有相當強的智能,才能將用戶請求分發到正確的機器上。
2、將session保存在單一的數據源中,這個數據源可被集群中所有的機器所共享,但帶來的問題就是性能問題了。
解決方案:是把session以Cookie的形式保存在客戶端。
優點:極高的擴展性和可用性
通過良好的編程,控制保存在cookie中的session對象的大小。
通過加密和安全傳輸技術(SSL),減少cookie被破解的可能性。
只在cookie中存放不敏感數據,即使被盜也不會有重大損失。
控制cookie的生命期,使之不會永遠有效。偷盜者很可能拿到一個過期的cookie。
缺點:
Cookie數量和長度的限制。每個domain最多只能有20條cookie,每個cookie長度不能超過4KB,否則會被截掉。
安全性問題。如果cookie被人攔截了,那人就可以取得所有的session信息。即使加密也與事無補,因為攔截者並不需要知道cookie的意義,他只要原樣轉發cookie就可以達到目的了。
有些狀態不可能保存在客戶端。例如,為了防止重複提交表單,我們需要在服務器端保存一個計數器。如果我們把這個計數器保存在客戶端,那麼它起不到任何作用。
來源: loyung
沒有留言:
張貼留言