session和cookie


為什么我們要使用session和cookie

為什么要使用session和cookie這個話題就要從HTTP狀態協議的無狀態性開始說起了。

無狀態協議是指協議對事物處理沒有記憶能力。缺少狀態意味着如果后續處理需要前面的信息,則必須重傳,這樣可能導致每次連接傳送的數據量增大。另一方面,在服務器不需要先前信息時它應答就很快。

HTTP是超本文傳輸協議,顧名思義,這個協議支持超文本的傳輸。什么是超文本?說白了就是使用HTML編寫的頁面。通常,我們使用客戶端瀏覽器訪問服務器的資源,最常見的URL也是以html為后綴的文件,因此可以說超文本是網絡上最主要的資源。

既然HTTP協議的目的是在於支持超文本的傳輸,也就是資源的傳輸,那么客戶端瀏覽器向HTTP服務器發送請求,繼而HTTP服務器將相信資源發回給客戶端這樣一個過程中,無論對於客戶端還是服務器,都沒有必要記錄這個過程,因為每一次請求和響應都是相對獨立的,就像我們在自動售貨機前投下硬幣購買商品一樣,沒必要記錄這個交易過程。一般而言,一個URL對應着一個唯一的超文本,而HTTP服務器也絕對公平公正,無論是誰,都會根據接收到的URL請求返回相同的超文本。正是因為這樣的唯一性,使得記錄用戶的行為狀態變得毫無意義,所以,HTTP協議被設計為無狀態的連接協議符合它本身的需求。

HTTP協議這種特性有優點也有缺點,優點在於解放了服務器,每一次請求"點到為止",不會造成不必要的連接占用,缺點在於每次請求都會傳輸大量的重復信息內容。

為了解決HTTP傳輸大量重復信息內容的問題,cookie和session就登場了,它們可以為用戶保存狀態。

 

cookie

cookie是通過客戶端保持狀態的解決方案。從定義上說,cookie就是服務器發送給客戶端的特殊信息,而這些信息以文本文件的方式存放在客戶端,然后客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息。

更具體一點說,當用戶使用瀏覽器訪問一個支持cookie的網站的時候,會有如下步驟:

1、用戶會提供包括用戶名在內的個人信息並且提交至服務器

2、服務器在向客戶端會傳相應的超文本的同時,發回這些個人信息。當然這些信息並不是存放在HTTP響應體(Response Body)中的,而是存放在HTTP響應頭(Response Header)中的

3、當客戶端瀏覽器收到來自服務器的響應之后,瀏覽器會將這些信息存放在一個統一的位置

4、之后,客戶端再向服務器發送請求的時候,都會把相應的cookie再次返回至服務器,而這次,cookie信息則存放在HTTP請求頭中了

比方說,我請求了一次http://www.sina.com.cn/,請求頭中帶了這么多cookie的信息:

 

可能覺得這個cookie比較亂,搞個清楚版本的:

簡單解釋一下這張表格:

1、NAME=VALUE,鍵值對,cookie包括session都是以鍵值對的形式存儲的

2、Domain,指的是生成該Cookie的域名

3、Path,指的是該Cookie是在哪個路徑下生成的

4、Expires / Max-Age,指的是該Cookie的過期時間/最大失效時間(即多少秒之后失效)

5、Size,這個很明顯,指的是占用的字節大小

6、Secure,如果設置了這個屬性,那么只會在SSH連接時才會回傳該cookie

有了cookie這樣的技術實現,服務器在接收到來自客戶端瀏覽器的請求之后,就能夠通過分析存放於請求頭中的cookie信息得到來自客戶端特有的信息,從而動態生成與客戶端相對應的內容。cookie在電腦中的存放地址為:

我的電腦是Win8的,在C:\Users\dell1\AppData\Local\Microsoft\Windows\INetCache

也可以通過IE瀏覽器來打開:瀏覽器-->工具-->Internet選項-->瀏覽器歷史記錄-->設置-->查看文件

 

session

session是相對於cookie的另外一個解決方案,它是通過服務器來保持狀態的。session指的是服務器為客戶端所開辟的存儲空間,在其中保存的信息就是用於保存狀態的。

首先,session是服務器端程序運行的過程中創建的,不同語言實現的應用程序有不同創建session的方法。在創建了session的同時,服務器會為該session生成唯一的sessionId,而這個sessionId被創建了之后,就可以調用session相關的方法往session中增加內容了,而這些內容只會保存在服務器中,發送到客戶端的只有sessionId。當客戶端再次發送請求時,會將這個sessionId帶上,服務器收到請求之后就會根據sessionId找到對應的session,從而再次使用。這樣的一個過程,讓用戶的狀態得以保持。

其次,每個session都有一個sessionId,這個ID存放在哪里?有兩種方式:

1、通過URL存取,URL會帶上一個;jsessionId=xxxxxx等,這樣每次重新請求的時候都傳了sessionId給服務器

2、通過cookie存取(Tomcat默認如此),這種cookie是session cookie,區別於persistent cookies也就是我們常說的cookie,session cookie要注意的是存儲在瀏覽器內存中(至於瀏覽器內存在哪里,這是和瀏覽器相關的,比方說我用的是360瀏覽器,那就在360se6\User Data\Default這個路徑下)而不是寫到硬盤上。程序一開始執行,服務器就生成一個sessionId並通過cookie攜帶客戶端瀏覽器的緩存中,當下一次訪問的時候,服務器先檢測一下是否有這個cookie,如果有就取它的ID,如果沒有就再生成一個。這就是為什么關閉瀏覽器之后,再進去session已經沒有了,其實在服務器端session並沒有清空,而是sessionId變了。

再者,瀏覽器關閉,session沒有了的說法是不正確的。如果瀏覽器關閉,服務器保存的session數據不是立即釋放的,此時數據還會存在,只要我們知道那個sessionId,就可以繼續通過請求獲得此session的信息。session里面的數據都放在服務器端,通過sessionId保證不會訪問錯誤,服務端自動對session進行管理,如果在規定的時間內沒有訪問,則釋放掉這個session。

最后提兩點:

1、sessionId通常是看不到的,但是當我們把瀏覽器的cookie禁止之后,Web服務器會采用URL重寫的方式傳遞sessionId,這樣就可以在地址欄看到sessionId了

2、session cookie不可以跨窗口使用

 

再談cookie和session

cookie和session各有優缺點,在大型互聯網系統中,單獨使用cookie和session都是不可行的,使用cookie有如下缺點:

1、使用cookie來傳遞信息,隨着cookie個數的增多和訪問量的增加,它占用的網絡帶寬也很大,試想假如cookie占用200字節,如果一天的PV有幾個億,那么它要占用多少帶寬?

2、cookie並不安全,因為cookie是存放在客戶端的,所以這些cookie可以被訪問到,設置可以通過插件添加、修改cookie。所以從這個角度來說,我們要使用sesssion,session是將數據保存在服務端的,只是通過cookie傳遞一個sessionId而已,所以session更適合存儲用戶隱私和重要的數據

不過session也有缺點:

1、不容易在多態服務器之間共享,這是致命的弱點

2、session存放在服務器中,所以session如果太多會非常消耗服務器的性能

既然如此,我們就可以揚長避短,利用cookie和session各自優點,規避它們的缺點,開發一套分布式的session框架出來,當然這是后話了,之后可能會寫一篇文章專門將這個。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM