Cookie與Session的認識與理解
一.引入這兩種技術的原因
因為HTTP是無狀態的協議,無法根據之前的狀態繼續處理後續的請求。也就是說在HTTP下,伺服器無法分辨誰已經瀏覽過了某一網頁,對於使用者登入的情況,因為該協議無法記錄登入狀態,所以會導致每次跳轉新的頁面需要再次登入或者在每次的請求報文中新增引數來管理登陸狀態。
雖然這種無狀態的協議能夠有效減少伺服器cpu與記憶體的消耗,但是在某些情況下是非常不利於使用者操作的,因此,為了能夠讓伺服器記住使用者的登陸狀態以及瞭解使用者購物車添加了哪些商品,先後出現了四種技術,分別是隱藏表單域、URL重寫、cookie、session。
本文主要討論的技術是cookie、session。
二者應用場景:
登入網站,今輸入使用者名稱密碼登入了,第二天再開啟很多情況下就直接打開了。這個時候用到的一個機制就是cookie。
購物車,添加了商品之後客戶端處可以知道添加了哪些商品,而伺服器端如何判別呢,所以也需要儲存一些資訊就用到了session。
二.Cookie
Cookie通俗講,是訪問某些網站後在本地儲存的一些網站相關資訊,下次訪問時減少一些步驟。更準確的說法是:Cookies是伺服器在本地機器上儲存的小段文字並隨每一個請求傳送至同一伺服器,是在客戶端保持狀態的方案。
<1>Cookie的處理流程:
- 伺服器向客戶端傳送cookie
- 瀏覽器將cookie儲存
- 之後每次http請求瀏覽器都會將cookie傳送給伺服器端
<2>組成部分
Cookie的主要內容包括:名字,值,過期時間,路徑和域。使用Fiddler抓包就可以看見。
- name:一個唯一確定的cookie名稱。通常來講cookie的名稱是不區分大小寫的。
- value:儲存在cookie中的字串值。最好為cookie的name和value進行url編碼
- domain:cookie對於哪個域是有效的。所有向該域傳送的請求中都會包含這個cookie資訊。這個值可以包含子域(如:yq.aliyun.com),也可以不包含它(如:.aliyun.com,則對於aliyun.com的所有子域都有效).
- path: 表示這個cookie影響到的路徑,瀏覽器跟會根據這項配置,像指定域中匹配的路徑傳送cookie。
- expires:失效時間,表示cookie何時應該被刪除的時間戳(也就是,何時應該停止向伺服器傳送這個cookie)。如果不設定這個時間戳,瀏覽器會在頁面關閉時即將刪除所有cookie;不過也可以自己設定刪除時間。這個值是GMT時間格式,如果客戶端和伺服器端時間不一致,使用expires就會存在偏差。
- max-age: 與expires作用相同,用來告訴瀏覽器此cookie多久過期(單位是秒),而不是一個固定的時間點。正常情況下,max-age的優先順序高於expires。
- HttpOnly: 告知瀏覽器不允許通過指令碼document.cookie去更改這個值,同樣這個值在document.cookie中也不可見。但在http請求張仍然會攜帶這個cookie。注意這個值雖然在指令碼中不可獲取,但仍然在瀏覽器安裝目錄中以檔案形式存在。這項設定通常在伺服器端設定。
- secure: 安全標誌,指定後,只有在使用SSL連結時候才能傳送到伺服器,如果是http連結則不會傳遞該資訊。就算設定了secure 屬性也並不代表他人不能看到你機器本地儲存的 cookie 資訊,所以不要把重要資訊放cookie就對了
<3>瀏覽器程序間共享cookie
儲存在硬碟上的cookie可以在不同的瀏覽器程序間共享,比如兩個IE視窗。
而對於儲存在記憶體裡的cookie,不同的瀏覽器有不同的處理方式。對於IE,在一個開啟的視窗上按Ctrl-N(或者從檔案選單)開啟的視窗可以與原視窗共享,而使用其他方式新開的IE程序則不能共享已經開啟的視窗的記憶體cookie;對於Mozilla Firefox0.8,所有的程序和標籤頁都可以共享同樣的cookie。一般來說是用javascript的window.open開啟的視窗會與原視窗共享記憶體cookie。瀏覽器對於會話cookie的這種只認cookie不認人的處理方式經常給採用session機制的web應用程式開發者造成很大的困擾。
三.Session
Session存在伺服器的一種用來存放使用者資料的類HashTable結構。
瀏覽器第一次傳送請求時,伺服器自動生成了一HashTable和一Session ID來唯一標識這個HashTable,並將其通過響應傳送到瀏覽器。瀏覽器第二次傳送請求會將前一次伺服器響應中的Session ID放在請求中一併傳送到伺服器上,伺服器從請求中提取出Session ID,並和儲存的所有Session ID進行對比,找到這個使用者對應的HashTable。
一般這個值會有個時間限制,超時後毀掉這個值,預設30分鐘。
當用戶在應用程式的 Web頁間跳轉時,儲存在 Session 物件中的變數不會丟失而是在整個使用者會話中一直存在下去。
Session的實現方式和Cookie有一定關係。建立一個連線就生成一個session id,開啟幾個頁面就好幾個了,這裡就用到了Cookie,把session id存在Cookie中,每次訪問的時候將Session id帶過去就可以識別了.
四.Cookie與Session區別
<1>儲存資料量方面:
session 能夠儲存任意的 java 物件,cookie 只能儲存 String 型別的物件,且單個cookie儲存的資料不能超過4K,很多瀏覽器都限制一個站點最多儲存20個cookie。
<2>儲存位置:
cookie儲存在客戶端,session儲存在服務端。因Cookie在客戶端所以可以編輯偽造,不是十分安全。
<3>資源限制:
Session過多時會消耗伺服器資源,大型網站會有專門Session伺服器,Cookie存在客戶端沒問題。
<4>支援範圍:
域的支援範圍不一樣,比方說a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解決這個問題的辦法是JSONP或者跨域資源共享。