爲何咱們要使用session和cookiehtml
爲何要使用session和cookie這個話題就要從HTTP狀態協議的無狀態性開始提及了。瀏覽器
無狀態協議是指協議對事物處理沒有記憶能力。缺乏狀態意味着若是後續處理須要前面的信息,則必須重傳,這樣可能致使每次鏈接傳送的數據量增大。另外一方面,在服務器不須要先前信息時它應答就很快。緩存
HTTP是超本文傳輸協議,顧名思義,這個協議支持超文本的傳輸。什麼是超文本?說白了就是使用HTML編寫的頁面。一般,咱們使用客戶端瀏覽器訪問服務器的資源,最多見的URL也是以html爲後綴的文件,所以能夠說超文本是網絡上最主要的資源。安全
既然HTTP協議的目的是在於支持超文本的傳輸,也就是資源的傳輸,那麼客戶端瀏覽器向HTTP服務器發送請求,繼而HTTP服務器將相信資源發回給客戶端這樣一個過程當中,不管對於客戶端仍是服務器,都沒有必要記錄這個過程,由於每一次請求和響應都是相對獨立的,就像咱們在自動售貨機前投下硬幣購買商品同樣,不必記錄這個交易過程。通常而言,一個URL對應着一個惟一的超文本,而HTTP服務器也絕對公平公正,不管是誰,都會根據接收到的URL請求返回相同的超文本。正是由於這樣的惟一性,使得記錄用戶的行爲狀態變得毫無心義,因此,HTTP協議被設計爲無狀態的鏈接協議符合它自己的需求。服務器
HTTP協議這種特性有優勢也有缺點,優勢在於解放了服務器,每一次請求"點到爲止",不會形成沒必要要的鏈接佔用,缺點在於每次請求都會傳輸大量的重複信息內容。cookie
爲了解決HTTP傳輸大量重複信息內容的問題,cookie和session就登場了,它們能夠爲用戶保存狀態。網絡
cookiesession
cookie是經過客戶端保持狀態的解決方案。從定義上說,cookie就是服務器發送給客戶端的特殊信息,而這些信息以文本文件的方式存放在客戶端,而後客戶端每次向服務器發送請求的時候都會帶上這些特殊的信息。框架
更具體一點說,當用戶使用瀏覽器訪問一個支持cookie的網站的時候,會有以下步驟:分佈式
一、用戶會提供包括用戶名在內的我的信息而且提交至服務器
二、服務器在向客戶端會傳相應的超文本的同時,發回這些我的信息。固然這些信息並非存放在HTTP響應體(Response Body)中的,而是存放在HTTP響應頭(Response Header)中的
三、當客戶端瀏覽器收到來自服務器的響應以後,瀏覽器會將這些信息存放在一個統一的位置
四、以後,客戶端再向服務器發送請求的時候,都會把相應的cookie再次返回至服務器,而此次,cookie信息則存放在HTTP請求頭中了
比方說,我請求了一次http://www.sina.com.cn/,請求頭中帶了這麼多cookie的信息:
可能以爲這個cookie比較亂,搞個清楚版本的:
簡單解釋一下這張表格:
一、NAME=VALUE,鍵值對,cookie包括session都是以鍵值對的形式存儲的
二、Domain,指的是生成該Cookie的域名
三、Path,指的是該Cookie是在哪一個路徑下生成的
四、Expires / Max-Age,指的是該Cookie的過時時間/最大失效時間(即多少秒以後失效)
五、Size,這個很明顯,指的是佔用的字節大小
六、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存放在哪裏?有兩種方式:
一、經過URL存取,URL會帶上一個;jsessionId=xxxxxx等,這樣每次從新請求的時候都傳了sessionId給服務器
二、經過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。
最後提兩點:
一、sessionId一般是看不到的,可是當咱們把瀏覽器的cookie禁止以後,Web服務器會採用URL重寫的方式傳遞sessionId,這樣就能夠在地址欄看到sessionId了
二、session cookie不能夠跨窗口使用
再談cookie和session
cookie和session各有優缺點,在大型互聯網系統中,單獨使用cookie和session都是不可行的,使用cookie有以下缺點:
一、使用cookie來傳遞信息,隨着cookie個數的增多和訪問量的增長,它佔用的網絡帶寬也很大,試想假如cookie佔用200字節,若是一天的PV有幾個億,那麼它要佔用多少帶寬?
二、cookie並不安全,由於cookie是存放在客戶端的,因此這些cookie能夠被訪問到,設置能夠經過插件添加、修改cookie。因此從這個角度來講,咱們要使用sesssion,session是將數據保存在服務端的,只是經過cookie傳遞一個sessionId而已,因此session更適合存儲用戶隱私和重要的數據
不過session也有缺點:
一、不容易在多態服務器之間共享,這是致命的弱點
二、session存放在服務器中,因此session若是太多會很是消耗服務器的性能
既然如此,咱們就能夠揚長避短,利用cookie和session各自優勢,規避它們的缺點,開發一套分佈式的session框架出來,固然這是後話了,以後可能會寫一篇文章專門將這個。