如果你對于session 和cookie 隻有一點模糊了解,那麼此篇文章能幫你用簡單的方式更深入了解session和cookie ,這篇文章會告訴你這些:
為什麼要有session 和cookie?
Session 和cookie它們是如何工作的?
session和cookie 它們有什麼聯系,又有什麼差別?
1、為什麼要有session 和cookie?
萬物皆有它存在的理由,至于session 和cookie 為什麼會出現那麼我們隻能問他的親爹http了,就像我們生了個兒子是為了延續後代,有人養老送終,http養了這兩個兒子又是為什麼呢?是以我們首先得了解一下這個親爹;
1-1、什麼是Http?
Http協定即超文本傳送協定 (HTTP-Hypertext transfer protocol) ,它是基于 TCP/IP 協定的應用層協定。它不涉及資料包傳輸,主要規定了用戶端和伺服器之間的通信格式。
簡單的說,http 是網際網路請求資料傳輸的一種規範,它規定了用戶端與伺服器之間互相通信的資料格式規則。它是基于TCP/IP協定之上的應用層協定,這就好像球類運動(TCP/IP)和足球(HTTP)的關系,在球類運動裡規定一個隻能用腳踢的球類運動規則,這類規則形成的運動名字就叫足球。
HTTP 協定一共有幾個特點:支援客戶/伺服器模式;簡單快速;靈活;無連接配接,無狀态。其中HTTP無狀态的特性将和我們今天的主題有密切關系。
1-2、http 的無狀态
http 是一種無狀态的協定,”無狀态”其實這種描述有點模糊,這裡的無狀态更精确的說法應該是”
不儲存請求的狀态資訊”的意思,http要做的事就是規範WEB資料傳輸格式,協定本身不會對請求和響應的通信狀态進行儲存。
至于http什麼要這麼做,主要有下面幾個原因:
1、職責單一化:既然我是個協資料傳輸協定,那麼我就隻做協定層需要做的事情,儲存臨時請求狀态類的資訊那是緩存的功能。
2、友善擴充:隻有把一件事情做的越簡單,那麼它的伸縮性才越好,
比如:如果你是生産自來水的,那你安安心心隻生産自來水就行了,這樣的話那些生産任何飲料的都可以從你這裡進貨,隻要需要自來水的地方都可以和你合作。但是結果你為了水的味道好一點,在水裡面加了一點糖,這樣就會造成做茶類的飲料沒辦法和你合作了,因為茶裡面是不需要加糖的。
3、提升效率:不需要儲存額外的資訊請求的速度當然要快一些。
1-3、http的無狀态帶來的問題
因為http是不儲存狀态資訊的,是以這就意味着兩次請求之間是沒辦法建立聯系,這就造成了前一個請求已經做過的事情,後面的請求還是照樣要做一次。
比如我們最常見的系統功能”登入驗證”:
我們系統很多功能都需要進行登入才可以操作,比如說,檢視個人資訊、下單、加好友.........等等;
這裡如果我們不儲存使用者登入的狀态資訊,那麼我每次檢視個人資訊之前都需要先進行登入,然後才能檢視到個人資訊,那麼多個請求就會以這樣的形式展現出來。
檢視個人資訊請求:登入=>檢視個人資訊
下單請求: 登入=>下單
加好友請求: 登入=>發送好友申請
當你看到上面的請求執行情況,你應該就發現了問題,明顯登入其實隻要做一次就行了,那麼我們是否可以在使用者第一次登入後就把使用者的登入狀态儲存起來呢,以後的請求隻需要通過這個狀态來判斷使用者是否有進行登入,那麼是否就能避免使用者需要重複的登入呢? 是以就出現了我們的http狀态保持方案,cookie 和session;
2、Http無狀态解決方案之Cookie
cookie是把請求狀态存儲在用戶端的一種解決方案;因為http的無狀态,我們無法識别曆史請求的狀态資訊,是以就想出了一個辦法,服務端會在每個用戶端第一次請求的時候頒發一個通行證,不管服務端和用戶端都可以往這個通信證裡存入狀态資訊,然後交由用戶端儲存,用戶端以後每次向伺服器發起請求的時候都會帶上這個通行證,通過在這種方式來保持請求之間的聯系。
2-1、cookie生成和操作。
(1)java操作cookie//擷取cookie
Cookie[] cookies= request.getCookies();//添加cookie
Cookie cookie=
newCookie(
"name",
"susan");//設定有效時間(秒)
cookie.setMaxAge(1000);//當請求是HTTPS或者其他安全協定時才傳輸cookie
cookie.setSecure(
true);//設定cookie是否能通過 js 通路
cookie.setHttpOnly(
true);//設定cookie作用域 doman+path形成一個cookie作用範圍
cookie.setDomain(
"http://baidu.com");
cookie.setPath(
"/user");
response.addCookie(cookie);
(2)前端javascript操作cookie//擷取cookie
document.cookie
//設定cookie
document.cookie = "name=Jonh; ";
通過頁面我們可以看到,每次請求伺服器通過response設定cookie 後,用戶端每次請求都會把cookie存到request header 裡傳給伺服器。
2-2、cookie屬性修改
雖然服務端可以生成添加cookie,但是服務端是無法直接修改用戶端傳輸過來的cookie的值的,服務端隻能通過建立一個名稱相同的cookie來覆寫想修改的cookie,浏覽器發現有相同名稱的cookie時隻會保留最新的發送給伺服器。
比如你想修改名稱為A的cookie那麼可以建立一個名稱為A的cookie來覆寫它。
Cookie cookie=
newCookie(
"A",
"1111");
response.addCookie(cookie);
2-3、删除cookie
主動設定有效期删除
Cookie并沒有提供直接删除的方法,我們隻能通過setMaxAge(-1)設定有效期來簡介達到删除cookie的效果。
持久cookie:如果通過setMaxAge設定了cookie的有效期時間大于0,則浏覽器會把該cookie持久化到磁盤,然後根據設定的時間判斷過期則失效。
臨時cookie:當通過setMaxAge設定cookie的有效時間為負數,此時的cookie就屬于一個臨時cookie,臨時cookie隻會儲存在用戶端記憶體裡面,當浏覽器關閉後就會失效。
3、Http無狀态解決方案之session
session是把狀态資訊儲存在服務端的一種解決方案,那麼為什麼有了Cookie之後還需要有seesion呢,其實我們在了解cookie的特點後知道我們的cookie是存儲在用戶端的,是以會存在一些不可控的問題,比如說cookie可以被竊取,而且cookie的大小也被用戶端所限制,是以會存在一些不安全的因素,是以那就隻能把狀态資訊儲存到服務端,交給服務端自己控制,而session則就是服務端保持狀态的解決方案。
Session是如何生成的?
當用戶端(浏覽器)通路服務端時服務端首先會讀取cookie;
如果cookie裡面包含一個JSESSIONID的值,那麼服務端會根據對應的JSESSIONID 從記憶體裡面擷取對應的session。
如果cookie 沒有JSESSIONID 那麼服務端會認為這是使用者第一次通路,那麼就會新生成一個session儲存到記憶體裡面,然後把session的唯一ID添加到cookie裡面,就鍵的名稱就是我們上面的JSESSIONID。
服務端生成session并把seesion的ID添加到cookie裡面後,用戶端每次請求通路都會帶上cookie。
Session是如何删除的?
1、服務端可以設定session的逾時時間,session逾時後會被删除。
2、調用HttpSession.invalidate()方法删除sesion。
3、伺服器程序停止。
cookie被禁用如何使用sesion?
我們從session使用流程中可以知道,其實session雖然是服務端儲存的,但是也還是需要用戶端的配合才能使用,而這個配合通常都是cookie來儲存session的sesion ID,然後用戶端每次都帶上cookie,服務端通過sesion ID來識别用戶端的身份。
但是這樣有一個問題,我們知道用戶端是可以禁用cookie的,如果用戶端禁用了cookie後我們如何傳遞這個session ID呢。
如果cookie禁用後,我們通常可以通過URL重寫和增加隐藏字段的方式來傳輸session ID,其原理就是在用戶端所有請求裡面都添加一個JSESSIONID的參數,服務端再通過擷取這個參數來識别用戶端的請求。這種方式雖然能解決sesion ID 傳遞的問題,但是在存在一些問題,是以很少使用。
4、Cookie 和sesion差別和關系
session安全性要高于cookieCookie是存儲在用戶端 Session是存儲在服務端,用戶端可以和操作Cookie但是無法操作session;雖然session ID也是存儲在cookie裡面的,但最多隻會暴露出session ID,但把資訊存儲在cookie裡面,一旦cookie 被竊取,那麼意味着所有的資訊都暴露了,。
Session會對伺服器性能影響也正是由于session是存儲在服務端的,而服務端面臨的用戶端是千千萬萬,而為每個用戶端都儲存一個session資訊也無形之間增加了服務端的負荷,而cookie是存在用戶端,這種壓力就會被分攤到每個用戶端。
Cookie 會增加網絡傳輸的負荷每次http請求都會攜帶上cookie,而不論你的目前請求有沒有用到cookie裡的資訊, 這樣的話大量請求都會攜帶一些沒有必要的資訊,是以cookie裡面的資料越大,無形中間額外增加了請求中不必要的資料傳輸,
Cookie 容量的限制Seesion 容量限制受制與伺服器的配置,可以進行擴容,理論上是沒有大小和個數限制的,而Cookie的大小是由浏覽器限制的,不同浏覽器的限制也不相同,是以我們沒辦法動态的擴充cookie的容量,使用cookie的時候要盡量避免資料過多超過浏覽器限制則會丢失資料。
Session 和 cookie 互相依賴因為session ID 是通過cookie 來儲存傳輸的,是以session的使用一定程度的依賴于cookie,在禁用cookie的情況下也會造成session無法正常使用,雖然有對應的解決方案,但是很少使用。
S}Y0§2 ��V