cookie

問題

HTTP協議是一種無狀態的協議,Web服務器自己不能識別出哪些請求是同一個瀏覽器發出的,瀏覽器的每一次請求都是徹底孤立的。
web服務器怎麼惟一地標識一個用戶,並記錄該用戶的狀態?web

會話與狀態管理

會話指一個客戶端與web服務器之間連續發生的一系列請求和響應過程。(就像把電話拿起到最後掛斷)。
會話狀態指web服務器與瀏覽器在會話過程當中產生的狀態信息,藉助會話狀態,web服務器把屬於同一會話中的一系列請求和響應過程關聯起來。跨域

web服務器要從大量的請求消息中區分出哪些請求屬於同一會話,即能識別出來自同一個瀏覽器的訪問請求,這須要瀏覽器對其發出的每一個請求消息都進行標識:屬於同一個會話中的請求消息都附帶一樣的標識號,屬於不一樣會話的請求消息附帶不一樣的標識號,這個標識號就稱爲會話ID。數組

servlet規範中,有兩種機制完成會話跟蹤:
cookiesession瀏覽器

cookie

是客戶端保持HTTP狀態信息的一種方案。
瀏覽器訪問web服務器的某個資源時,由web服務器在HTTP響應消息頭中附帶傳送給瀏覽器的一個小文本文件(Set-Cookie響應頭字段)。如:安全

Set-Cookie: bid=8UKoeCtJT1M; Expires=Sat, 25-Apr-20 04:02:11 GMT; Domain=.douban.com; Path=/

一旦web瀏覽器保存了某個cookie,那麼它在之後每次訪問該web瀏覽器時都會在HTTP請求頭中(Cookie請求頭字段)將這個cookie回傳給web服務器。如:服務器

Cookie: bid=8UKoeCtJT1M;

若是瀏覽器不支持Cookie(如大部分手機中的瀏覽器)或者把Cookie禁用了,Cookie功能就會失效。
不一樣的瀏覽器採用不一樣的方式保存Cookie。
IE瀏覽器會在C:\Documents and Settings\你的用戶名\Cookies文件夾下以文本文件形式保存,一個文本文件保存一個Cookie。cookie

建立cookie

httpServletResponse.addCookie(cookie);
該方法並不修改以前的Set-Cookie報頭,而是建立新的報頭。網絡

一個web站點能夠給一個web瀏覽器發送多個cookie,一個瀏覽器也能存儲多個web站點提供的cookie(每一個站點最多存放20個)。一個cookie(大小限制爲4kb)只能標識一種信息,它至 少含有一個標識該信息的k-v。 session

Cookie的值。若是值爲Unicode字符,須要爲字符編碼。若是值爲二進制數據,則須要使用BASE64編碼。dom

獲取cookie

httpServletRequest.getCookies()
讀取全部cookie返回數組,遍歷經過cookie.getName()篩選出本身要的(new Cookie()時的第一個參數)。

修改cookies

若是要修改某個Cookie,只須要新建一個同名的Cookie,添加到response中覆蓋原來的Cookie。

注意:修改、刪除Cookie時,新建的Cookie除value、maxAge以外的全部屬性,例如name、path、domain等,都要與原Cookie徹底同樣。不然,瀏覽器將視爲兩個不一樣的Cookie不予覆蓋,致使修改、刪除失敗。

cookie屬性設置

setMaxAge()

cookie的時效性:
默認狀況下新建的cookie是一個會話級別的cookie(會話cookie),存儲在瀏覽器內存中,用戶關閉瀏覽器後被刪除。

若但願瀏覽器將該cookie存儲在磁盤上(持久cookie),須要使用maxAge,並給出一個以秒爲單位的時間。
若是爲負數,該Cookie爲臨時Cookie,關閉瀏覽器即失效,瀏覽器也不會以任何形式保存該Cookie。這種cookie直到超過設定的過時時間才被刪除。若是爲0,表示刪除該Cookie。默認爲–1。

setPath()

cookie的做用範圍:
默認是當前目錄以及子目錄,不能做用於上一級目錄。
能夠本身設置cookie的做用範圍:
setPath(request.getContextPath)
「/」表示站點的根目錄,若是設置爲「/」,則本域名下contextPath均可以訪問該Cookie。

setDomain()

Cookie是不可跨域名的。域名www.google.com頒發的Cookie不會被提交到域名www.baidu.com去。這是由Cookie的隱私安全機制決定的。隱私安全機制可以禁止網站非法獲取其餘網站的Cookie。

正常狀況下,同一個一級域名下的兩個二級域名如www.baidu.com和images.baidu.com也不能交互使用Cookie,由於兩者的域名並不嚴格相同。若是想全部baidu.com名下的二級域名均可以使用該Cookie,須要設置Cookie的domain參數爲.baidu.com。

能夠修改本機hosts文件來配置多個臨時域名來驗證domain屬性。

注意:domain參數必須以點(".")開始。另外,name相同但domain不一樣的兩個Cookie是兩個不一樣的Cookie。若是想要兩個域名徹底不一樣的網站共有Cookie,能夠生成兩個Cookie,domain屬性分別爲兩個域名,輸出到客戶端。

setSecure()

HTTP協議不只是無狀態的,並且是不安全的。使用HTTP協議的數據不通過任何加密就直接在網絡上傳播,有被截獲的可能。使用HTTP協議傳輸很機密的內容是一種隱患。若是不但願Cookie在HTTP等非安全協議中傳輸,能夠設置Cookie的secure屬性爲true。瀏覽器只會在HTTPS和SSL等安全協議中傳輸此類Cookie。設置secure屬性爲true的代碼是cookie.setSecure(true);

secure屬性並不能對Cookie內容加密,於是不能保證絕對的安全性。若是須要高安全性,須要在程序中對Cookie內容加密(不可逆加密的)、解密,以防泄密。

其餘屬性

expires:失效時間,表示cookie什麼時候應該被刪除的時間戳(也就是,什麼時候應該中止向服務器發送這個cookie)。若是不設置這個時間戳,瀏覽器會在頁面關閉時即將刪除全部cookie;不過也能夠本身設置刪除時間。這個值是GMT時間格式,若是客戶端和服務器端時間不一致,使用expires就會存在誤差。

HttpOnly: 告知瀏覽器不容許經過腳本document.cookie去更改這個值,一樣這個值在document.cookie中也不可見。但在http請求張仍然會攜帶這個cookie。注意這個值雖然在腳本中不可獲取,但仍然在瀏覽器安裝目錄中以文件形式存在。這項設置一般在服務器端設置。

應用場景

自動登入

購物車,最近瀏覽過的商品

相關文章
相關標籤/搜索