關於 cookie 使用中遇到的問題

   前段時間在一個項目中涉及到cookie的存取,因而打算封裝一個 cookie 的CRUD 。按理來講,這自己是一個很簡單的問題,不注意的話簡單的問題也有大坑。git

  1 /**
  2  * Set or get cookie ;parse to object
  3  *
  4  *@date 2015-04-11
  5  *
  6  *@author 飄搖的楓葉
  7  *
  8  *
  9  *
 10  */
 11 'use strict';
 12 (function (window) {
 13     // class2type  refer to zepto.js $.type(obj) ## https://github.com/madrobby/zepto
 14     var class2type = {},
 15         toString = class2type.toString;
 16     "Boolean Number String Function Array Date RegExp Object Error".split(" ").forEach(function(name) {
 17         class2type["[object " + name + "]"] = name.toLowerCase();
 18     });
 19 
 20     var _qcookie = {
 21         cookies: document.cookie,
 22         get: function(name) {
 23             return this.all()[name];
 24         },
 25         /*
 26          *Set cookie
 27          *
 28          *@param    {string}  cookieName 
 29          *@param    {string}   cookieValue
 30          *  or
 31          *@param    {object}   cookieObject{key:value}
 32          *
 33          *@param    {object}   options{path:'/demo';domain:'/';expire:new Date();secure:0|1}
 34          */
 35         set: function(name, value, options) {
 36             var opt = options || {};
 37             if (!name) return;
 38             if (type(name) === 'string' && value) {
 39                 this.write(name, value, opt);
 40             } else if (type(name) === 'object') {
 41                 opt = value || {};
 42                 for (var k in name) {
 43                     this.write(k, name[k], opt);
 44                 }
 45             }
 46             // if (type(name) === 'string' && value) {
 47             //     str = encode(name) + '=' + encode(value) + '; ';
 48             // } else if (type(name) === 'object') {
 49             //     opt = value || {};
 50             //     for (var k in name) {
 51             //         str += encode(k) + '=' + encode(name[k]) + '; ';
 52             //     }
 53             // }
 54             // if (opt.path) str += 'path=' + opt.path;
 55             // if (opt.domain) str += 'domain=' + opt.domain;
 56             // if (opt.expires) str += 'expires=' + opt.expires.toUTCString();
 57             // if (opt.secure) str += 'secure';
 58             // document.cookie = str;
 59         },
 60         all: function() {
 61             return this.parse(this.cookies);
 62         },
 63         delete: function(name) {
 64             var expires = new Date();
 65             expires.setDate(expires.getDate() - 1);
 66             document.cookie = name + "=" + this.get(name) + '; expires=' + expires.toUTCString();
 67         },
 68         write: function(name, value, opt) {
 69             var str = encode(name) + '=' + encode(value);
 70             if (opt.path) str += '; path=' + opt.path;
 71             if (opt.domain) str += '; domain=' + opt.domain;
 72             if (opt.expires) str += '; expires=' + opt.expires.toUTCString();
 73             if (opt.secure) str += '; secure';
 74             document.cookie = str;
 75         },
 76         parse: function(cookieStr) {
 77             var obj = {};
 78             var arrs = cookieStr.split(/ *; */); // Similar with the split(';') + trim()
 79             var kv = [];
 80             if (arrs[0] == '') {
 81                 return obj;
 82             }
 83             for (var i = 0; i < arrs.length; i++) {
 84                 kv = arrs[i].split('=');
 85                 obj[decode(kv[0])] = decode(kv[1]);
 86             }
 87             return obj;
 88         }
 89     }
 90 
 91     function encode(str) {
 92         return encodeURIComponent(str);
 93     }
 94 
 95     function decode(str) {
 96         return decodeURIComponent(str);
 97     }
 98 
 99     function type(obj) {
100         return obj == null ? String(obj) :
101             class2type[toString.call(obj)] || "object"
102     }
103     window.qcookie = _qcookie;
104 })(window)

  仔細一看你會發現這裏面會有個很嚴重的問題,當不一樣域或者不一樣path的同名cookie 在讀和刪除的時候都會有問題 ,因爲 cookie 的 domain , path 等屬性是隻寫的,你讀取到的兩個cookie 結構多是徹底同樣的,根本沒法區分,相似這樣,github

因爲我採用的是將cookie parse 一個對象, 當你只傳一個name 的時候,第二個 'aaa' 必然會將第一個 'aaa' 的值給覆蓋掉,,這個問題一時間還真沒想到什麼好的辦法解決,又或者設計的時候壓根就沒有考慮過這個問題,由於實際項目中可能並不會出現這麼看上去很傻X的使用場景,然而多瞭解一點老是極好的。api

而刪除的話,cookie 自己並無提供刪除的api , cookie 的刪除徹底是已寫cookie的方式,加上一個失效時間,因此刪除時指定path cookie 經過設置domain , path 仍是能夠作到的。cookie

相關文章
相關標籤/搜索