前面介紹了cookie和session的區別,這裏讀起來是有收穫的,可是不作實驗老是感受不少東西浮在表面上,因此這裏來作一下實驗,看一下相應的知識點。node
這裏使用最簡單的node express,搭建一個簡單的web服務器,相關命令以下:web
mkdir cookie-test && cd cookie-test npm init npm install express --save touch main.js
命令執行完成以後會發現已經有以下的結構出來,咱們只須要編輯main.js便可:express
cookie-test |- main.js |- node_modules |- package.json
編輯代碼,輸入:npm
const express = require('express') const app = express() app.listen(3000, err => { if (err) { return console.log(err) } console.log('---- 打開 http://localhost:3000 吧----') }) app.get('/', (req, res) => { res.send('<h1>hello world!</h1>') })
這樣就創建起一個簡單的web服務器,咱們來設置幾個cookie看下。json
在設置cookie前,咱們先回顧一下cookie的工做原理:瀏覽器
1. 首先,咱們假設當前域名下仍是沒有 Cookie 的 2. 接下來,瀏覽器發送了一個請求給服務器(這個請求是還沒帶上 Cookie 的) 3. 服務器設置 Cookie 併發送給瀏覽器(固然也能夠不設置) 4. 瀏覽器將 Cookie 保存下來 5. 接下來,之後的每一次請求,都會帶上這些 Cookie,發送給服務器
咱們來驗證一下,修改代碼,加上下面的一行:安全
app.get('/', (req, res) => { res.cookie('key0', 'value0') res.send('<h1>hello world!</h1>') })
重啓服務器後看一下整個請求的過程: 首次請求中在request中沒有包括key0=value0的cookie,在response中帶了key0的cookie,第二次請求後: 已經帶了key0的cookie。咱們能夠在console裏看一下當前的cookie值,使用 document.cookie
就能夠查看: 確實已經有了key0的cookie。 下面總結一下什麼是cookie:服務器
1. Cookie 就是瀏覽器儲存在用戶電腦上的一小段文本文件 2. Cookie 是純文本格式,不包含任何可執行的代碼 3. Cookie 由鍵值對構成,由分號和空格隔開 4. Cookie 雖然是存儲在瀏覽器,可是一般由服務器端進行設置 5. Cookie 的大小限制在 4kb 左右
前面咱們講過,cookie的內容主要包括:名字,值,過時時間,路徑和域,咱們梳理一下前面的內容,作一個概括總結:cookie
1. cookie的內容主要包括:名字,值,過時時間,路徑和域 2. 路徑與域合在一塊兒就構成了cookie的做用範圍 3. 若是不設置過時時間,則表示這個cookie的生命期爲瀏覽器會話期間,只要關閉瀏覽器窗口,cookie就消失了
屬性就是對自身包含的內容設置一些特殊參數的東西,好比何時過時等等,下面咱們就來看cookie的屬性。session
expires / max-age 都是控制 Cookie 失效時刻的選項。若是沒有設置這兩個選項,則默認有效期爲 session,即會話 Cookie。這種 Cookie 在瀏覽器關閉後就沒有了。
expires 選項用來設置 Cookie 什麼時間內有效,expires 實際上是 Cookie 失效日期。 expires 必須是 GMT 格式的時間(能夠經過 new Date().toGMTString() 或者 new Date().toUTCString() 來得到) 咱們修改一下代碼:
app.get('/', (req, res) => { res.cookie('key0', 'value0') res.cookie('key1', 'value1', { expires: new Date(Date.now() + 10000) }) res.send('<h1>hello world!</h1>') })
這裏設置了10s的失效時間,咱們來看一下實際運行的狀況: 發現已經設置了expire的過時時間,這時候在console裏執行如下代碼:
console.log(`如今的 cookie 是:${document.cookie}`) setTimeout(() => { console.log(`5 秒後的 cookie 是:${document.cookie}`) }, 5000) setTimeout(() => { console.log(`10 秒後的 cookie 是:${document.cookie}`) }, 10000)
觀察到如下現象: 10s以後,key1的cookie已經失效了。 ######max-age expires 是 http/1.0 協議中的選項,在新的 http/1.1 協議中 expires 已經由 max-age 選項代替,二者的做用都是限制 Cookie 的有效時間。expires 的值是一個時間點 (Cookie 失效時刻 = expires),而 max-age 的值是一個以秒爲單位時間段 (Cookie 失效時刻 = 建立時刻 + max-age) 當二者都存在的時候,以max-age的值爲準:
res.cookie('key2', 'value2', { maxAge: 10000, }) res.cookie('key3', 'value3', { maxAge: 15000, expires: new Date(Date.now() + 10000) })
咱們看一下實際的運行效果:
1. key1只有設置了expire,所以只有expire的值; 2. key2只有設置max-age,會默認把max-age和expire設置成同樣的值; 3. key3 max-age和expire設置了不一樣的值,所以cookie裏過時時間也不同;
console運行以前的代碼,修改打印cookie的時間,得出如下結果: 這裏console打印的內容沒改,可是等待的時間已經變成10s 15s,分析一下上面的數據:
1. key2 max-age=10s,在10s後失效; 2. key3 expire=10s max-age=15s,在15s後失效,符合「以max-age的值爲準」的結論;
name、domain 和 path 能夠標識一個惟一的 Cookie。domain 和 path 兩個選項共同決定了 Cookie 什麼時候被瀏覽器自動添加到請求頭部中發送出去。 若是沒有設置這兩個選項,則會使用默認值。domain 的默認值爲設置該 Cookie 的網頁所在的域名,path 默認值爲設置該 Cookie 的網頁所在的目錄。
secure 選項用來設置 Cookie 只在確保安全的請求中才會發送。當請求是 HTTPS 或者其餘安全協議時,包含 secure 選項的 Cookie 才能被保存到瀏覽器或者發送至服務器。 默認狀況下,Cookie 不會帶 secure 選項(即爲空)。因此默認狀況下,不論是 HTTPS 協議仍是 HTTP 協議的請求,Cookie 都會被髮送至服務端。
這個選項用來設置 Cookie 是否能經過 js 去訪問。默認狀況下,Cookie 不會帶 httpOnly 選項(即爲空),客戶端是能夠經過 js 代碼去訪問(包括讀取、修改、刪除等)這個 Cookie 的。當 Cookie 帶 httpOnly 選項時,客戶端則沒法經過 js 代碼去訪問(包括讀取、修改、刪除等)這個 Cookie。 相應的實驗能夠經過設置
res.cookie('httpOnlyTest', 'testValue', { httpOnly: true })
來實驗,會發如今console裏打印cookie的時候沒有httpOnlyTest這個cookie值。
domain和path分別指代的是做用域和路徑,咱們先來看看域名的部分定義:
子域,是相對父域來講的,指域名中的每個段。各子域之間用小數點分隔開。放在域名最後的子域稱爲最高級子域,或稱爲一級域,在它前面的子域稱爲二級域。
如下圖爲例,news.163.com 和 sports.163.com 是子域,163.com 是父域。 當 Cookie 的 domain 爲 news.163.com,那麼訪問 news.163.com 的時候就會帶上 Cookie; 當 Cookie 的 domain 爲 163.com,那麼訪問 news.163.com 和 sports.163.com 就會帶上 Cookie
當 Cookie 的 domain 是相同的狀況下,也有是否帶上 Cookie 也有必定的規則。 在子路徑內能夠訪問訪問到父路徑的 Cookie,反過來就不行。
明確一點:Cookie 能夠由服務端設置,也能夠由客戶端設置。看到這裏相信你們均可以理解了吧。
1. 一個 Set-Cookie 字段只能設置一個 Cookie,當你要想設置多個 Cookie,須要添加一樣多的 Set-Cookie 字段 2. 服務端能夠設置 Cookie 的全部選項:expires、domain、path、secure、HttpOnly
在網頁即客戶端中咱們也能夠經過 js 代碼來設置 Cookie。 能夠設置 Cookie 的下列選項:expires、domain、path,各個鍵值對之間都要用 ; 和 空格 隔開
document.cookie='name=value; expires=Thu, 26 Feb 2116 11:50:25 GMT; domain=sankuai.com; path=/';
只有在 https 協議的網頁中,客戶端設置 secure 類型的 Cookie 才能成功
客戶端中沒法設置 HttpOnly 選項
Cookie 的 name、path 和 domain 是惟一標識一個 Cookie 的。咱們只要將一個 Cookie 的 max-age 設置爲 0,就能夠刪除一個 Cookie 了。
let removeCookie = (name, path, domain) => { document.cookie = `${name}=; path=${path}; domain=${domain}; max-age=0` }