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 最常见的的格式如下所示:
name=value&name1=value1&name2=value2&name3=value3&name4=value4&name5=value5
子 cookie 一般也以查询字符串的格式进行格式化。然后这些值可以使用单个 cookie 进行存储和访问,而非对每个名称键值对儿使用不同的 cookie 存储。最后网站或者 Web 应用程序可以无需达到单域名cookie 上限也可以存储更加结构化的数据。
为了更好地操作子 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);
}
};
- get()获取单个子cookie的值,接收两个参数:cookie的名字和子cookie的名字。其实就是调用getAll()获取所有的子cookie,然后只返回所需的那一个(如果cookie不存在则返回null)。
- getAll()获取所有子cookie并将它们放入一个对象中返回,对象的属性为子cookie的名称,对应值为子cookie对应的值。
- set()方法接收7个参数:cookie名称、子cookie名称、子cookie值、可选的cookie失效日期或时间的Date对象、可选的 cookie路径、可选的cookie域和可选的布尔secure标志。所有的可选参数都是作用于cookie本身而非子cookie。在这个方法中,第一步是获取指定cookie名称对应的所有子cookie。逻辑或操作符“||”用于当 getAll()返回null时将subcookies设置为一个新对象。然后,在subcookies对象上设置好子cookie值并传给setAll()。
- setAll()方法接收6个参数:cookie名称、包含所有子cookie的对象以及和set()中一样的4个可选参数。这个方法使用 for-in循环遍历第二个参数中的属性。为了确保确实是要保存的数据,使用了hasOwnProperty()方法,来确保只有实例属性被序列化到子cookie中。由于可能会存在属性名为空字符串的情况,所以在把属性名加入结果对象之前还要检查一下属性名的长度。将每个子cookie的名值对儿都存入subcookieParts数组中,以便稍后可以使用join()方法以 & 号组合起来。剩下的方法则和CookieUtil.set()一样。
- unset()方法用于删除某个cookie中的单个子cookie而不影响其他的;
- 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");
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。