cookie工具函數封裝

cookie工具函數

let CookieUtil = {
    get: function (name){
        let cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null;
        if (cookieStart > -1){
            let cookieEnd = document.cookie.indexOf(";", cookieStart);
            if (cookieEnd == -1){
                cookieEnd = document.cookie.length;
            }
            cookieValue = decodeURIComponent(document.cookie.substring(cookieStart + cookieName.length, cookieEnd));
        }
        return cookieValue;
    },
    set: function (name, value, expires, path, domain, secure) {
        let cookieText = encodeURIComponent(name) + "=" + encodeURIComponent(value);
        if (expires instanceof Date) {
            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.set(name, "", new Date(0), path, domain, secure);
    }
};

CookieUtil.get() 方法根據 cookie 的名字獲取相應的值。它會在 document.cookie 字符串中查找 cookie 名加上等於號的位置。若是找到了,那麼使用 indexOf() 查找該位置以後的第一個分號(表示了該 cookie 的結束位置)。若是沒有找到分號,則表示該 cookie 是字符串中的最後一個,則餘下的字符串都是 cookie 的值。該值使用 decodeURIComponent() 進行解碼並最後返回。若是沒有發現 cookie,則返回 null 。數組

CookieUtil.set() 方法在頁面上設置一個 cookie,接收以下幾個參數:cookie的名稱,cookie的值,可選的用於指定 cookie什麼時候應被刪除的 Date 對象,cookie的可選的 URL路徑,可選的域,以及可選的表示是否要添加 secure 標誌的布爾值。參數是按照它們的使用頻率排列的,只有頭兩個是必需的。在這個方法中,名稱和值都使用 encodeURIComponent() 進行了URL編碼,並檢查其餘選項。若是 expires參數是 Date 對象,那麼會使用 Date 對象的 toGMTString() 方法正確格式化 Date 對象,並添加到expires 選項上。方法的其餘部分就是構造 cookie字符串並將其設置到 document.cookie 中。沒有刪除已有 cookie 的直接方法。因此,須要使用相同的路徑、域和安全選項再次設置 cookie,並將失效時間設置爲過去的時間。瀏覽器

CookieUtil.unset() 方法能夠處理這種事情。它接收 4 個參數:要刪除的 cookie 的名稱、可選的路徑參數、可選的域參數和可選的安全參數。這些參數加上空字符串並設置失效時間爲 1970 年 1 月 1 日(初始化爲 0ms的 Date 對象的值),傳給 CookieUtil.set() 。這樣就能確保刪除 cookie安全

//設置 cookie
CookieUtil.set("name", "Nicholas");
CookieUtil.set("book", "Professional JavaScript");
//讀取 cookie 的值
alert(CookieUtil.get("name")); //"Nicholas"
alert(CookieUtil.get("book")); //"Professional JavaScript"
//刪除 cookie
CookieUtil.unset("name");
CookieUtil.unset("book");
//設置 cookie,包括它的路徑、域、失效日期
CookieUtil.set("name", "Nicholas", "/books/projs/", "www.wrox.com", new Date("January 1, 2010"));
//刪除剛剛設置的 cookie
CookieUtil.unset("name", "/books/projs/", "www.wrox.com");
//設置安全的 cookie
CookieUtil.set("name", "Nicholas", null, null, null, true);

子cookie

爲了繞開瀏覽器的單域名下的 cookie 數限制,一些開發人員使用了一種稱爲子 cookie(subcookie)的概念。子 cookie 是存放在單個 cookie 中的更小段的數據。也就是使用 cookie 值來存儲多個名稱值對。子 cookie 最多見的的格式以下所示:cookie

name=value&name1=value1&name2=value2&name3=value3&name4=value4&name5=value5

子 cookie 通常也以查詢字符串的格式進行格式化。而後這些值可使用單個 cookie 進行存儲和訪問,而非對每一個名稱鍵值對兒使用不一樣的 cookie 存儲。最後網站或者 Web 應用程序能夠無需達到單域名cookie 上限也能夠存儲更加結構化的數據。dom

爲了更好地操做子 cookie,必須創建一系列新方法。子 cookie 的解析和序列化會因子 cookie 的指望用途而略有不一樣並更加複雜些。例如,要得到一個子 cookie,首先要遵循與得到 cookie 同樣的基本步驟,可是在解碼 cookie 值以前,須要按以下方法找出子 cookie 的信息。函數

let SubCookieUtil = {
    get: function (name, subName){
        let subCookies = this.getAll(name);
        if (subCookies){
            return subCookies[subName];
        } else {
            return null;
        }
    },
    getAll: function(name){
        let cookieName = encodeURIComponent(name) + "=",
            cookieStart = document.cookie.indexOf(cookieName),
            cookieValue = null,
            cookieEnd,
            subCookies,
            i,
            parts,
            result = {};
        if (cookieStart > -1){
            cookieEnd = document.cookie.indexOf(";", cookieStart);
            if (cookieEnd == -1){
                cookieEnd = document.cookie.length;
            }
            cookieValue = document.cookie.substring(cookieStart + cookieName.length, cookieEnd);
            if (cookieValue.length > 0){
                subCookies = cookieValue.split("&");
                for (i=0, len=subCookies.length; i < len; i++){
                    parts = subCookies[i].split("=");
                    result[decodeURIComponent(parts[0])] =
                    decodeURIComponent(parts[1]);
                }
                return result;
            }
        }
        return null;
    },
    set: function (name, subName, value, expires, path, domain, secure) {
        let subcookies = this.getAll(name) || {};
        subcookies[subName] = value;
        this.setAll(name, subcookies, expires, path, domain, secure);
    },
    setAll: function(name, subcookies, expires, path, domain, secure){
        let cookieText = encodeURIComponent(name) + "=",
            subcookieParts = new Array(),
            subName;
        for (subName in subcookies){
            if (subName.length > 0 && subcookies.hasOwnProperty(subName)){
                subcookieParts.push(encodeURIComponent(subName) + "=" + encodeURIComponent(subcookies[subName]));
            }
        }
        if (cookieParts.length > 0){
            cookieText += subcookieParts.join("&");
            if (expires instanceof Date) {
                cookieText += "; expires=" + expires.toGMTString();
            }
            if (path) {
                cookieText += "; path=" + path;
            }
            if (domain) {
                cookieText += "; domain=" + domain;
            }
            if (secure) {
                cookieText += "; secure";
            }
        } else {
            cookieText += "; expires=" + (new Date(0)).toGMTString();
        }
        document.cookie = cookieText;
    },
    unset: function (name, subName, path, domain, secure){
        let subcookies = this.getAll(name);
        if (subcookies){
            delete subcookies[subName];
            this.setAll(name, subcookies, null, path, domain, secure);
        }
    },
    unsetAll: function(name, path, domain, secure){
        this.setAll(name, null, new Date(0), path, domain, secure);
    }
};
  1. get()獲取單個子cookie的值,接收兩個參數:cookie的名字和子cookie的名字。其實就是調用getAll()獲取全部的子cookie,而後只返回所需的那一個(若是cookie不存在則返回null)。
  2. getAll()獲取全部子cookie並將它們放入一個對象中返回,對象的屬性爲子cookie的名稱,對應值爲子cookie對應的值。
  3. set()方法接收7個參數:cookie名稱、子cookie名稱、子cookie值、可選的cookie失效日期或時間的Date對象、可選的 cookie路徑、可選的cookie域和可選的布爾secure標誌。全部的可選參數都是做用於cookie自己而非子cookie。在這個方法中,第一步是獲取指定cookie名稱對應的全部子cookie。邏輯或操做符「||」用於當 getAll()返回null時將subcookies設置爲一個新對象。而後,在subcookies對象上設置好子cookie值並傳給setAll()。
  4. setAll()方法接收6個參數:cookie名稱、包含全部子cookie的對象以及和set()中同樣的4個可選參數。這個方法使用 for-in循環遍歷第二個參數中的屬性。爲了確保確實是要保存的數據,使用了hasOwnProperty()方法,來確保只有實例屬性被序列化到子cookie中。因爲可能會存在屬性名爲空字符串的狀況,因此在把屬性名加入結果對象以前還要檢查一下屬性名的長度。將每一個子cookie的名值對兒都存入subcookieParts數組中,以便稍後可使用join()方法以 & 號組合起來。剩下的方法則和CookieUtil.set()同樣。
  5. unset()方法用於刪除某個cookie中的單個子cookie而不影響其餘的;
  6. unsetAll()方法則等同於CookieUtil.unset(),用於刪除整個cookie。

和set()及setAll() 同樣,路徑、域和 secure 標誌必須和以前建立的 cookie 包含的內容一致。針對整個 cookie 的失效日期則能夠在任何一個單獨的子cookie寫入的時候同時設置。工具

SubCookieUtil.getAll() 方法和 CookieUtil.get() 在解析 cookie 值的方式上很是類似。區別在於 cookie 的值並不是當即解碼,而是先根據 & 字符將子 cookie 分割出來放在一個數組中,每個子 cookie再根據等於號分割,這樣在 parts 數組中的前一部分即是子 cookie 名,後一部分則是子 cookie的值。這兩個項目都要使用 decodeURIComponent() 來解碼,而後放入 result 對象中,最後做爲方法的返回值。若是 cookie 不存在,則返回 null 。網站

//假設 document.cookie=data=name=Nicholas&book=Professional%20JavaScript
//取得所有子 cookie
var data = SubCookieUtil.getAll("data");
alert(data.name); //"Nicholas"
alert(data.book); //"Professional JavaScript"
//逐個獲取子 cookie
alert(SubCookieUtil.get("data", "name")); //"Nicholas"
alert(SubCookieUtil.get("data", "book")); //"Professional JavaScript"
//設置兩個 cookie
SubCookieUtil.set("data", "name", "Nicholas");
SubCookieUtil.set("data", "book", "Professional JavaScript");
//設置所有子 cookie 和失效日期
SubCookieUtil.setAll("data", { name: "Nicholas", book: "Professional JavaScript" }, new Date("January 1, 2010"));
//修更名字的值,並修改 cookie 的失效日期
SubCookieUtil.set("data", "name", "Michael", new Date("February 1, 2010"));
//僅刪除名爲 name 的子 cookie
SubCookieUtil.unset("data", "name");
//刪除整個 cookie
SubCookieUtil.unsetAll("data");
相關文章
相關標籤/搜索