因爲HTTP是一種無狀態的協議,服務器單從網絡鏈接上無從知道客戶身份。怎麼辦呢?就給客戶端們頒發一個通行證吧,每人一個,不管誰訪問都必須攜帶本身通行證。這樣服務器就能從通行證上確認客戶身份了。這就是Cookie的工做原理。git
Cookie其實是一小段的文本信息。客戶端請求服務器,若是服務器須要記錄該用戶狀態,就使用response向客戶端瀏覽器頒發一個Cookie。客戶端瀏覽器會把Cookie保存起來。當瀏覽器再請求該網站時,瀏覽器把請求的網址連同該Cookie一同提交給服務器。服務器檢查該Cookie,以此來辨認用戶狀態。服務器還能夠根據須要修改Cookie的內容。以下圖:
github
屬性項 | 屬性項介紹 |
---|---|
Name | 一個惟一肯定cookie的名稱(cookie名稱不區分大小寫,實踐中最好區分,由於一些服務器會區分),URL編碼 |
Value | 存儲cookie的字符串值,值必須通過URL編碼 |
Expires | 過時時間,在這個時間點後Cookie失效 |
Domain | 生成Cookie域名 |
Path | 該Cookie是在當前那個路徑下生成的 |
Secure | 加密設置,設置他以後,只會在SSL鏈接時纔會回傳該Cookie |
這裏我只要說二個點:
一、Expires:該Cookie失效的時間,單位秒。面試
二、Domain:
咱們如今有二個域名。域名A:b.f.com,域名B:d.f.com;顯然域名A和域名B都是f.com的子域名算法
若是域名A沒有顯式設置Cookie的domain方法,那麼domain就爲.b.f.com,不同的是,這時,域名A的子域名將沒法獲取這個Cookie數據庫
HttpOnly: 這個屬性是面試的時候常考的,若是這個屬性設置爲true,就不能經過js腳原本獲取cookie的值,能有效的防止xss攻擊
因爲js沒有給原生的操做方法,咱們能夠簡單地封裝一下:跨域
var cookieUtil = { getItem: function (name) { var cookieName = encodeURIComponent(name) + "=", cookieStart = document.cookie.indexOf(cookieName), cookieValue = null; if (cookieStart > -1) { var cookieEnd = document.cookie.indexOf(';', cookieStart); if (cookieEnd == 1) { cookieEnd = document.cookie.length; } cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd)) } return cookieValue; }, setItem: function (name, value, expires, path, domain, secure) { var cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value); if (expires) { cookieText += ";expires=" + expires.toGMTString(); } if (path) { cookieText += ";path=" + path; } if (domain) { cookieText += ";domain=" + domain; } if (secure) { cookieText += ";secure"; } document.cookie = cookieText; }, unset: function (name, path, domain, secure) { this.setItem(name, "", new Date(0), path, domain, secure) } } CookieUtil.setItem("name", 'tom'); // 設置cookie console.log(CookieUtil.getItem('name'));//讀取cookie CookieUtil.unset("name")//刪除cookie
由於Cookie是存儲在客戶端,用戶能夠隨意修改。因此,存在必定的安全隱患。瀏覽器
防篡改簽名:服務器爲每一個Cookie項生成簽名。若是用戶篡改Cookie,則與簽名沒法對應上。以此,來判斷數據是否被篡改。
原理以下:安全
舉個栗子:
好比服務器接收到請求中的Cookie項username=pony|34Yult8i,而後使用簽名生成算法secret(pony)=666。 算法獲得的簽名666和請求中數據的簽名不一致,則證實數據被篡改。服務器
Session: 是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據能夠保存在集羣、數據庫、文件中.爲了得到更高的存取速度,服務器通常把Session放在內存裏。每一個用戶都會有一個獨立的Session。若是Session內容過於複雜,當大量客戶訪問服務器時可能會致使內存溢出。所以,Session裏的信息應該儘可能精簡。cookie
當客戶端請求建立一個session的時候,服務器會先檢查這個客戶端的請求裏是否已包含了一個session標識 - sessionId,
sessionId的值通常是一個既不會重複,又不容易被仿造的字符串,這個sessionId將被在本次響應中返回給客戶端保存。保存sessionId的方式大多狀況下用的是cookie。
session 的運行依賴 session id,而 session id 是存在 cookie中的
若是客戶端的瀏覽器禁用了 Cookie怎麼辦?通常這種狀況下,會使用一種叫作URL重寫的技術來進行會話跟蹤,(在 url 中傳遞 session_id)即每次HTTP交互,URL後面都會被附加上一個諸如 sid=xxxxx 這樣的參數,服務端據此來識別用戶。
cookie | session | |
---|---|---|
存儲位置 | 客戶端 | 服務器端 |
存取方式 | 只能保管ASCII字符串 | 夠存取任何類型的數據 |
有效期不一樣 | Cookie能夠設置過時時間屬性 | JSESSIONID的過時時間默許爲–1,只需關閉了閱讀器該Session就會失效 |
服務器壓力 | Cookie保管在客戶端,不佔用服務器資源。假如併發閱讀的用戶十分多,Cookie是很好的選擇 | Session是保管在服務器端的,每一個用戶都會產生一個Session。假如併發訪問的用戶十分多,會產生十分多的Session,耗費大量的內存 |
跨域支持上的不一樣 | Cookie支持跨域名訪問,例如將domain屬性設置爲「.biaodianfu.com」,則以「.biaodianfu.com」爲後綴的一切域名均可以訪問該Cookie。 | Session則不會支持跨域名訪問。Session僅在他所在的域名內有效。 |
區分路徑 | cookie中若是設置了路徑參數,那麼同一個網站中不一樣路徑下的cookie互相是訪問不到的 | session不能區分路徑,同一個用戶在訪問一個網站期間,全部的session在任何一個地方均可以訪問到 |
若是有錯誤或者不嚴謹的地方,請務必給予指正,十分感謝。若是喜歡或者有所啓發,歡迎 star對做者也是一種鼓勵。