JavaScript Cookie

瀏覽器 (browser) 的 cookie 可以用來儲存一些使用者的連線資料,例如儲存使用者登入狀態的 session 資料。cookie 會一直儲存在使用者的瀏覽器中,直到你指定的失效日期為止,不論 server 端或使用者 (瀏覽器) 端都可以讀取和寫入 cookie 資料。

在使用者端我們可以用 JavaScript 來管理瀏覽器的 cookie,而不論是讀取或是寫入 cookie 都是統一使用 document.cookie 物件:

// 讀取
allCookies = document.cookie;

// 寫入
document.cookie = newCookie;

下面的語法用來建立一個新的 cookie:

document.cookie = newCookie;

JavaScript 一次只能建立一個新 cookie,newCookie 是一個 key=value 格式的字串,後面還可以加上這些設定:

  • ;path=path 設定能讀取到此 cookie 的路徑,例如 ;path=/ 表示讓整個網站都讀取得到,預設為目前網頁所在的路徑。
  • ;domain=domain 設定能讀取到此 cookie 的網域,例如 ;domain=fooish.com 表示讓子網域 (subdomain) 像是 www.fooish.com, blog.fooish.com 都能讀取得到,預設為目前網頁的網域。
  • ;max-age=max-age-in-seconds 設定 cookie 的存活期限,單位為秒,例如 86400 就是一天後失效。
  • ;expires=date-in-GMTString-format 設定 cookie 的存活期限,值是一個 Date.toUTCString() 格式的時間字串,這個參數在 HTTP 1.1 之後已經被 max-age 取代。
  • ;secure 設定 cookie 只能於 https 連線中被傳送。

設定一個新 cookie 只有 key=value 部分是必要的,其他部分都可以省略。

當一個 cookie 沒有設定失效時間,就是所謂的 session cookie (有設定失效時間的則稱 persistent cookie),該 cookie 會在使用者關閉瀏覽器後被自動刪除。

用法:

// 設定兩個 cookie 叫 test1, test2
// 在瀏覽器關閉後會自動被刪除
document.cookie = 'test1=Hello';
document.cookie = 'test2=World';

// 設定一個 username cookie 裡面的值是 Mike,儲存一個月
document.cookie = 'username=Mike; max-age=2592000; path=/';

另外,為了避免 cookie 值裡面有特殊字元像是 ; 會破壞語法格式,你可以統一用 encodeURIComponent() 函數來做 value encode:

document.cookie = 'foo=' + encodeURIComponent(anyValue);

document.cookie 用來讀取 cookie,但讀取出來是一個很長的字串,字串裡面是所有曾經儲存的 cookie,格式是 key=value,用分號 ; 分隔不同的 cookie。

例如:

// "cookie1=value; cookie2=value; cookie3=value"
var cookies = document.cookie;

是的,除了 key=value 你讀取不到 cookie 其他的設定參數。

但內建的方法沒有那麼好用,通常我們會自己寫一個方便讀取個別 cookie 的函數:

function parseCookie() {
    var cookieObj = {};
    var cookieAry = document.cookie.split(';');
    var cookie;
    
    for (var i=0, l=cookieAry.length; i<l; ++i) {
        cookie = jQuery.trim(cookieAry[i]);
        cookie = cookie.split('=');
        cookieObj[cookie[0]] = cookie[1];
    }
    
    return cookieObj;
}


function getCookieByName(name) {
    var value = parseCookie()[name];
    if (value) {
        value = decodeURIComponent(value);
    }

    return value;
}

我們就可以很方便的讀取 cookie,像是取得 username 的 cookie 只需要用 getCookieByName('username')

修改 Cookie 其實就是重新建立一個同名的 cookie 來直接覆蓋掉舊的。

刪除 cookie 也很簡單,你只需要設定一個已經過期的 expires 時間,像是 Thu, 01 Jan 1970 00:00:00 GMT

例如刪除 username 這一個 cookie:

document.cookie = 'username=; expires=Thu, 01 Jan 1970 00:00:00 GMT';

瀏覽器對 cookie 用量管理,各個瀏覽器的限制略有差異,但基本上有下面這些限制:

  • 最多可以有 300 個 cookie
  • 每個 cookie 小於 4096 bytes
  • 一個網站 (domain) 最多 20 個 cookie
  • 每個網站 (domain) 最多可以存有 81920 bytes 的 cookie